[SOLVED] Rebuild blank chip results in " Internet Available, Cloud not reachable " and " Handling cloud error: 3 "


Looking to fix my Electron (for the second time since purchase). The first time I fixed it the symptom was that strange errors started appearing (Electron would run for a few minutes, then send out an SOS hard fault). Then it stopped sending out SOS messages and would just get stuck on a RHB colour (i.e. just solid green, white, or blue). Eventually the RGB just stopped lighting up all together after running for 20 seconds or so.

So, I took my ST-LINK V2 and used the SWD programming interface to flash the bootloader and system firmware binaries listed in the JTAG and SWD guide.

That guide just has a hard-link to the bootloader bin file to use for the Electron. Not sure what bootloader version it is, but the text of the hyperlink says “Electron (0.4.8)” (see screenshot, below)

I flashed the booloader and system firmware as per the guide.

Using that guide successfully un-bricked my Electron the first time.

Now after running my application for about a week or so I am having the same symptoms again.

So I tried the steps outlined above for the second time but it didn’t seem to help. I just kept getting either SOS hard faults or would sometimes get a connecting to network rapid cyan flash followed by three yellow flashes and then the RGB turning off all-together.

So, I decided to nuke the STM32 with ST-Link utility by un-write protecting all sectors of the chip and fully erasing the chip. I then reflashed the booloader from the link in the guide and also reflashed system firmware and user application binary files (using the target sectors outlined in the guide).

I then put the device into DFU mode and ran particle keys doctor using Particle CLI. Here is the output from that:

C:\PARTICLE_LOCAL\JazaHub_Controller\Testing\FancyTinker\firmware>particle keys doctor 3f001xxxxxxxxxxxxxxxxxxxxx
Found DFU device 2b04:d00a
Found DFU device 2b04:d00a
New Key Created!
Found DFU device 2b04:d00a
Found DFU device 2b04:d00a
spawning dfu-util -d 2b04:d00a -a 1 -i 0 -s 3106:leave -D 3f001b000xxxxxxxxxxx_ec_new.der
dfu-util 0.8

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2014 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to dfu-util@lists.gnumonks.org

Opening DFU capable USB device...
ID 2b04:d00a
Run-time device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Setting #1 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 011a
Device returned transfer size 4096
DfuSe interface name: "DCT Flash   "
Downloading to address = 0x00000c22, size = 121
Download        [=========================] 100%          121 bytes
Download done.
File downloaded successfully
Invalid DFU suffix signature
A valid DFU suffix will be required in a future dfu-util release!!!
attempting to add a new public key for device 3f001b0xxxxxxxxxxxxxxxxxxxx
submitting public key succeeded!
Okay!  New keys in place, your device should restart.

So looks like the keys doctor worked right?

Here is the ElectronSerialPipe that results from trying to run a slightly modified version of Tinker (with logging, in threaded, semi-automatic mode):

0000003067 [app.main] WARN: Waiting for serial input before proceeding

0000004068 [app.main] WARN: Waiting for serial input before proceeding

0000005069 [app.main] WARN: Waiting for serial input before proceeding

0000006070 [app.main] WARN: Waiting for serial input before proceeding

0000007071 [app.main] WARN: Waiting for serial input before proceeding

0000008072 [app.main] WARN: Waiting for serial input before proceeding

0000009073 [app.main] WARN: Waiting for serial input before proceeding

0000010065 [app.main] INFO: Looping

0000010165 [system] INFO: Network Connect: !SPARK_WLAN_STARTED

0000010165 [system] INFO: ready(): 0; connecting(): 0; listening(): 0; WLAN_SMART_CONFIG_START: 0

[ ElectronSerialPipe::begin ] = = = = = = = =

[ Modem::powerOn ] = = = = = = = = = = = = = =

    10.467 AT send       4 "AT\r\n"

    10.477 AT read UNK   3 "AT\r"

    10.487 AT read OK    6 "\r\nOK\r\n"

    10.487 AT send       7 "AT E0\r\n"

    10.497 AT read UNK   6 "AT E0\r"

    10.507 AT read OK    6 "\r\nOK\r\n"

    10.507 AT send      11 "AT+CMEE=2\r\n"

    10.517 AT read OK    6 "\r\nOK\r\n"

    10.517 AT send      19 "AT+CMER=1,0,0,2,1\r\n"

    10.529 AT read OK    6 "\r\nOK\r\n"

    10.529 AT send      15 "AT+IPR=115200\r\n"

    10.539 AT read OK    6 "\r\nOK\r\n"

    10.639 AT send      10 "AT+CPIN?\r\n"

    10.649 AT read  +   16 "\r\n+CPIN: READY\r\n"

    10.659 AT read OK    6 "\r\nOK\r\n"

0000010669 [system] INFO: Sim Ready

0000010669 [system] INFO: ARM_WLAN_WD 1

[ Modem::init ] = = = = = = = = = = = = = = =

    10.661 AT send       9 "AT+CGSN\r\n"

    10.681 AT read UNK  19 "\r\n353162076295659\r\n"

    10.691 AT read OK    6 "\r\nOK\r\n"

    10.691 AT send       9 "AT+CGMI\r\n"

    10.701 AT read UNK  10 "\r\nu-blox\r\n"

    10.711 AT read OK    6 "\r\nOK\r\n"

    10.711 AT send       9 "AT+CGMM\r\n"

    10.721 AT read UNK  13 "\r\nSARA-U260\r\n"

    10.731 AT read OK    6 "\r\nOK\r\n"

    10.731 AT send       9 "AT+CGMR\r\n"

    10.741 AT read UNK   9 "\r\n23.20\r\n"

    10.751 AT read OK    6 "\r\nOK\r\n"

    10.751 AT send       9 "AT+CCID\r\n"

    10.771 AT read  +   30 "\r\n+CCID: 8934076500002661015\r\n"

    10.783 AT read OK    6 "\r\nOK\r\n"

    10.783 AT send      11 "AT+UPSV=1\r\n"

    10.793 AT read OK    6 "\r\nOK\r\n"

    10.793 AT send      11 "AT+CMGF=1\r\n"

    10.803 AT read OK    6 "\r\nOK\r\n"

    10.803 AT send      13 "AT+CNMI=2,1\r\n"

    10.813 AT read OK    6 "\r\nOK\r\n"

    10.813 AT send       9 "AT+CIMI\r\n"

    10.823 AT read UNK  19 "\r\n214074300556497\r\n"

    10.833 AT read OK    6 "\r\nOK\r\n"

[ Modem::register ] = = = = = = = = = = = = = =

    10.833 AT send      10 "AT+CREG?\r\n"

    10.845 AT read  +   14 "\r\n+CREG: 0,0\r\n"

    10.855 AT read OK    6 "\r\nOK\r\n"

    10.855 AT send      11 "AT+CGREG?\r\n"

    10.865 AT read  +   15 "\r\n+CGREG: 0,0\r\n"

    10.875 AT read OK    6 "\r\nOK\r\n"

    10.875 AT send      12 "AT+CGREG=2\r\n"

    10.885 AT read OK    6 "\r\nOK\r\n"

    10.885 AT send      11 "AT+CREG=2\r\n"

    10.895 AT read OK    6 "\r\nOK\r\n"

    10.895 AT send      10 "AT+CREG?\r\n"

    10.905 AT read  +   14 "\r\n+CREG: 2,0\r\n"

    10.915 AT read OK    6 "\r\nOK\r\n"

    10.915 AT send      11 "AT+CGREG?\r\n"

    10.925 AT read  +   15 "\r\n+CGREG: 2,0\r\n"

    10.935 AT read OK    6 "\r\nOK\r\n"

0000012066 [app.main] INFO: Looping

0000014068 [app.main] INFO: Looping

0000016070 [app.main] INFO: Looping

0000018072 [app.main] INFO: Looping

0000020074 [app.main] INFO: Looping

0000022076 [app.main] INFO: Looping

0000024078 [app.main] INFO: Looping

    25.935 AT send      10 "AT+CREG?\r\n"

    25.935 AT read  +   14 "\r\n+CIEV: 2,2\r\n"

    25.947 AT read  +   28 "\r\n+CREG: 5,\"03E8\",\"0210\",0\r\n"

    25.959 AT read  +   34 "\r\n+CGREG: 5,\"03E8\",\"0210\",0,\"01\"\r\n"

    25.971 AT read  +   14 "\r\n+CIEV: 3,1\r\n"

    25.981 AT read  +   14 "\r\n+CIEV: 7,1\r\n"

    25.991 AT read  +   14 "\r\n+CIEV: 9,2\r\n"

CIEV matched: 9,2

    26.001 AT read  +   14 "\r\n+CIEV: 2,3\r\n"

    26.011 AT read  +   14 "\r\n+CIEV: 2,2\r\n"

0000026079 [app.main] INFO: Looping

    27.051 AT read  +   30 "\r\n+CREG: 2,5,\"03E8\",\"0210\",0\r\n"

    27.063 AT read OK    6 "\r\nOK\r\n"

    27.063 AT send      11 "AT+CGREG?\r\n"

    27.073 AT read  +   36 "\r\n+CGREG: 2,5,\"03E8\",\"0210\",0,\"01\"\r\n"

    27.085 AT read OK    6 "\r\nOK\r\n"

    27.085 AT send      10 "AT+COPS?\r\n"

    27.125 AT read  +   43 "\r\n+COPS: 0,0,\"CAN Rogers Wireless Inc.\",0\r\n"

    27.137 AT read OK    6 "\r\nOK\r\n"

    27.137 AT send       9 "AT+CNUM\r\n"

    27.177 AT read OK    6 "\r\nOK\r\n"

    27.177 AT send       8 "AT+CSQ\r\n"

    27.187 AT read  +   15 "\r\n+CSQ: 15,99\r\n"

    27.197 AT read OK    6 "\r\nOK\r\n"

[ Modem::join ] = = = = = = = = = = = = = = = =

    27.197 AT send      12 "AT+CGATT=1\r\n"

    27.209 AT read OK    6 "\r\nOK\r\n"

    27.209 AT send      14 "AT+UPSND=0,8\r\n"

    27.219 AT read  +   17 "\r\n+UPSND: 0,8,0\r\n"

    27.229 AT read OK    6 "\r\nOK\r\n"

    27.229 AT send      23 "AT+UPSD=0,7,\"\"\r\n"

    27.241 AT read OK    6 "\r\nOK\r\n"

    27.241 AT send      36 "AT+UPSD=0,1,\"spark.telefonica.com\"\r\n"

    27.253 AT read OK    6 "\r\nOK\r\n"

    27.253 AT send      15 "AT+UPSD=0,6,0\r\n"

    27.263 AT read OK    6 "\r\nOK\r\n"

    27.263 AT send      14 "AT+UPSDA=0,3\r\n"

0000028080 [app.main] INFO: Looping

0000030081 [app.main] INFO: Looping

0000032082 [app.main] INFO: Looping

And then the Electron’s RGB LED goes totally dark… and I receive no more output to serial monitor… and then nothing.


So I’m guessing my STM32 is either irreparably broken at the silicon level, or that I need to flash more than just the bootloader and system firmware binaries to a blank chip?

I’m also worried that I have the wrong bootloader, since I can’t find any place to download a bootloader binary other than in the guide link previously mentioned


Here’s the process I used to rebuild the chip:

1) Set option bytes in ST-LINK Utility

For this step, I clicked Target->Option Bytes and then clicked “Unselect all” to disable write protection of flash sectors on the chip. See screenshot:

This resulted in the following console output:

13:28:02 : Option bytes updated successfully.

2) Erase chip

I clicked Target->Erase Chip in order to erase the flash memory of the STM32

Results in following console output:

13:29:23 : ST-LINK SN : 0674FF495351885087175924
13:29:23 : ST-LINK Firmware version : V2J27M15
13:29:23 : Connected via SWD.
13:29:23 : SWD Frequency = 4,0 MHz.
13:29:23 : Connection mode : Normal.
13:29:23 : Debug in Low Power mode enabled.
13:29:23 : Device ID:0x411 
13:29:23 : Device flash Size : 1MBytes
13:29:23 : Device family :STM32F2xx
13:30:46 : Flash memory erased.

##3) Confirm flash memory has been erased

For this step I just scrolled through the various addresses available in the address dropdown and made sure all memory addresses read “FF” as shown below:


##4) Flash bootloader and system firmware binaries to the STM32

Downloaded and flashed “the bootloader” (0.4.8???) and system firmware binaries (release/v0.6.0) as referenced in the JTAG and SWD guide. See screenshots:


5) Run Particle CLI keys doctor

Put the Electron into DFU mode and run particle keys doctor <device_ID>


6) Compile modified version of tinker

Source code:

#include "Particle.h"


//    System.enableFeature(FEATURE_RESET_INFO);          //Sets system flag that retains reset reason in memory for reporting after reset
//    System.enableFeature(FEATURE_RETAINED_MEMORY);     //Sets system flag that allows for our application to retain some variables even through power outage and reset
// );

SerialLogHandler logHandler(LOG_LEVEL_ALL, {
	{"app", LOG_LEVEL_ALL}

static Logger myLog("app.main");  //Logger object used in this "main.cpp" file

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

/* This function is called once at start up ----------------------------------*/
void setup()


	unsigned long serialWaitTimeStart = millis();
	unsigned long lastSerialWaitMesage = millis();

		if((millis() - serialWaitTimeStart) > 10000){
		if(millis() - lastSerialWaitMesage > 1000){
			myLog.warn("Waiting for serial input before proceeding");
			lastSerialWaitMesage = millis();

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


unsigned long lastLoopMessage = 0;
/* This function loops forever --------------------------------------------*/
void loop()

	if(millis() - lastLoopMessage > 2000){
		lastLoopMessage = millis();

 * 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;

		pinMode(pinNumber, INPUT_PULLDOWN);
		return digitalRead(pinNumber);
	else if (pin.startsWith("A"))
		pinMode(pinNumber+10, INPUT_PULLDOWN);
		return digitalRead(pinNumber+10);
	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;

		pinMode(pinNumber, OUTPUT);
		digitalWrite(pinNumber, value);
		return 1;
	else if(command.startsWith("A"))
		pinMode(pinNumber+10, OUTPUT);
		digitalWrite(pinNumber+10, value);
		return 1;
	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;

		return -3;
	else if (pin.startsWith("A"))
		return analogRead(pinNumber+10);
	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)
	//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;

	String value = command.substring(3);

		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 return -2;

Command line compiler screenshot:


7) Flash modified version of Tinker using dfu-util


NOTE: at this point my computer starts freaking out because the Electron appears to be recognized as a mouse, resulting in my cursor going all over the place! This didn’t happen the first time I followed the above steps!!! The first time I was able to get the serial monitor output shown above. So it would appear that this process is non-repeatable (making me think that it is a silicon issue with the chip)
EDIT 2: Okay, restarted my computer using keyboard only (my mouse stopped working after the Electron started making my computer flip out). I can no longer connect the Electron to my USB port without making my computer flip out, unless the Electron put into DFU mode first.

I just tried using “particle flash --usb tinker” while Electron was in DFU mode and my computer no longer thinks the Electron is a mouse. So, no serial debugging to help narrow down error. However, after running for about a minute and alternating between green flashing a cyan flashing, the RGB led stays stuck on solid green.

Trying to flash another version of simple program posted above compiled for v0.6.0 with no cloud functions registered and only serial debugging results in the same strange mouse-takeover behaviour… can’t even get it into listening mode.

Flashing tinker (I assume its version 0.6.1 or 0.6.2 when particle cli is version 1.21.0) using particle flash --usb tinker allows me to put the device into listening mode and retrieve the following using particle serial identify:

Tried building locally using firmware target 0.6.1 as per

$ make clean all PLATFORM=electron program-dfu

And now I am able to open the serial monitor and see the same process happening as was posted above, i.e.

0000154239 [system] INFO: Cloud: connecting

0000154240 [system] WARN: Cloud socket connection failed: -1

0000157270 [system] WARN: Internet available, Cloud not reachable!

0000157270 [system] WARN: Handling cloud error: 3

0000157270 [system] INFO: Cloud: connecting

0000157271 [system] WARN: Cloud socket connection failed: -1

0000157271 [system] WARN: Resetting WLAN due to 2 failed connect attempts

0000157842 [system] WARN: Internet available, Cloud not reachable!

0000157842 [system] WARN: Handling cloud error: 3

0000157842 [system] WARN: Resetting WLAN due to SPARK_WLAN_RESET

0000162683 [system] INFO: Network Connect: !SPARK_WLAN_STARTED

this is accompanied by the flashing cyan and two yellow blinks. Eventually it gets stuck and stops running from what I can tell (RGB is solid green)

here is the readout of particle serial inspect:

C:\Users\Boompy>particle serial inspect
Platform: 10 - Electron
  Bootloader module #0 - version 11, main location, 16384 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #1 - version 105, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #3 - version 105
  System module #2 - version 105, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #1 - version 105
  System module #3 - version 105, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  User module #1 - version 4, main location, 131072 bytes max size
    UUID: 2597554C4FC50D4EE3620530F187B72A7472D4346F5980269CA8A0987853B63A
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 105
  empty - factory location, 131072 bytes max size


  • Using web console, removed the device from the product it was registered to, then unclaiming the device, both of which succeeded.

  • Ran particle keys doctor , which succeeded.

  • Still getting same behaviour as above , i.e.
    [system] WARN: Handling cloud error: 3

  • invoking particle device add <device_ID> results in following error message in Particle-CLI:

    C:\Users\Boompy>particle device add 3f001b000xxxxxxxxxxx
    Claiming device 3f001b0003xxxxxxxxxxxxxxxx
    Failed to claim device, server said: Device is not connected


  • Now using local build of release/stable and getting the same results
  • This time it got stuck on soild cyan
  • Another time it got stuck with RGB totally off


  • Used local build of release/stable to generate bootloader, firmware, and app binaries
  • Flashed bootloader binary found in
    using ST-Link Utiliity
  • same results as before


  • Running particle server keys and then particle keys doctor resolved the problem. The Electron is now connecting and has been running for the last 12 hours. The step I had been missing before was to run the particle server keys command.

I’d like to commend you one of the most thoroughly researched troubleshooting efforts I’ve ever seen. I’m pretty sure the Electron has a hardware defect and we can replace it. Just submit a support ticket and reference this post and I’ll make sure it gets taken care of.

It’s not likely a boot loader issue because when you have a newer system firmware that contains a newer boot loader, it will just update the boot loader from system firmware at boot. At least through 0.6.x, it’s a little different in 0.7.0.

When you have no boot loader, Dim D7, you’re stuck and have to program it from JTAG/SWD. But if you have a working but older boot loader that can run system firmware, the system firmware is then able to upgrade the boot loader itself.




That’s that engineer documentation instinct in me I guess! I just submitted a support ticket.

Interesting that the newer firmware contains boot loader update/upgrade payloads, I didn’t realize that. I guess that explains why there is only one bootloader binary referenced in that Particle Guide you did on JTAG/SWD.

Hopefully this post will be helpful to anyone else who experiences strange behavior like this with their devices. :green_apple:

Just checking: if you trying to build an Electron from a totally wiped STM32, the only things you need to do are:

  1. Flash bootloader (1 sector of flash)
  2. Flash system firmware binaries (3 sectors of flash)
  3. Flash user application (1 sector of flash)
  4. Run particle keys doctor <device_id> to DFU secure key into flash memory of Electron (1 sector of flash)

So, there are only 6 sectors of flash memory that need to be populated in order to get the Electron up and running right?

As in the following screenshot from the Electron datasheets:

And then I presume that running particle keys doctor <device_id> will populate the following values in the DCD region:

Yes, that’s pretty much correct. If you’re using a device with a USB port you only need to flash the boot loader by JTAG/SWD, once you do that you can flash the system and user firmware by either DFU or JTAG/SWD.

Usually only one of DCD1 or DCD2 will contain data, the other is 0xFF bytes (erased). If you’re saving and restoring the configuration you can save both and restore both by JTAG/SWD. However, you can also just leave both erased and run particle keys server and particle keys doctor to update with new keys instead.

1 Like

Aha I got it to connect successfully by running:

particle server keys


particle keys doctor <device_id>

in CLI.

I don’t see “particle server keys” in the Particle CLI reference. I assume it is like running “particle keys server my_server.der” except it defaults to some particle-cli keys file instead of a specified one. Is that about right?

If you leave off the parameter (the .der file) for particle keys server it uses the production server keys. Note that there are different server keys files for TCP devices (Photon, P1, Core) and UDP devices (Electron). You still need to specify the .der file if you are using a local cloud.

Okay, so I guess Particle CLI just figures out which default keys file to use by detecting which type of device is connected and in DFU mode?

1 Like

@rickkas7, I might have missed this, but isn’t it required to get an authorised device ID for a bare STM32 device to hook up to the Particle cloud?
Otherwise any hardware could use the Particle services free of charge at the cost of Particle.

Yes, for a bare STM32 processor you do need to have it provisioned before it can access the Particle cloud.

But I think in this case it was an Electron that had all of its flash sectors erased to a blank state so the device ID was already provisioned.