No signal strength information for Electron 2G on Device OS 1.0.0

TL,DR; This issue is fixed in Device OS v1.0.1

I've been digging into this issue and found a reliable way to reproduce it:

  1. Use v1.0.0 firmware
  2. Power off completely
  3. Power up and only turn on the modem initially
  4. Wait a bit (20s LTE, 60s 2G/3G to be sure) and let the modem automatically register to the network in the background
  5. Particle.connect() now, or Cellular.connect() to cause the system to go through the registration process.
  6. It should see that it's already registered and not run *REG=2 which will later cause the RSSI command to fail return 1.
  7. Successive hard/soft resets of the STM32 and skipping step 4 will not clear this issue.

Example app to reproduce on v1.0.0 (running the same app on v1.0.1 will not show this RSSI=1 issue)

#include "Particle.h"
SYSTEM_MODE(SEMI_AUTOMATIC)
SerialLogHandler logHandler(LOG_LEVEL_ALL);

void setup()
{
    Cellular.on();
    delay(20000);
    Particle.connect();
}

void loop()
{
    static uint32_t lastUpdate;
    if (Cellular.ready() && millis() - lastUpdate > 5000UL) {
        lastUpdate = millis();
        CellularSignal sig = Cellular.RSSI();
        int rat = sig.getAccessTechnology();
        bool pgd = PMIC().isPowerGood();
        char rssiTest[32];
        snprintf(rssiTest, 32, "RAT:%d RSSI:%d QUAL:%d PGD:%d", rat, sig.rssi, sig.qual, pgd);
        Serial.printlnf("%s", rssiTest);
        if (Particle.connected()) {
            Particle.publish("rssi-test", rssiTest, PRIVATE);
        }
    }
}

The issue stems from this response:

     1.145 AT send      11 "AT+CEREG?\r\n"
     1.157 AT read  +   15 "\r\n+CEREG: 0,1\r\n"
     1.167 AT read OK    6 "\r\nOK\r\n"

When it should look like this:

   115.198 AT send      11 "AT+CEREG?\r\n"
   115.206 AT read  +   34 "\r\n+CEREG: 2,1,\"1234\",\"1234567\",8\r\n"
   115.208 AT read OK    6 "\r\nOK\r\n"

Root Cause of the problem

  1. In 0.8.0-rc.x we changed the Cellular.RSSI() API to calculate the correct RSSI in dB based on the type of RAT (Radio Access Technology) we are currently registered to the cellular tower with.
  2. Later in 0.8.0-rc.x we introduced LTE support and refactored a bunch of the mdm_hal.cpp firmware.
  3. By optimizing some code in mdm_hal.cpp it opened up a corner case that prevented the verbose URC response of +CEREG from being returned, which contains the RAT we are currently connected to.
  4. If the modem is power cycled and allowed to register before the Device OS knows about it (the modem does this registration with the tower automatically), Device OS firmware will initially see it's already registered and never issue the AT+CEREG=2 command for LTE (or AT+CREG=2 / AT+CGREG=2 for 2G/3G).
  5. Because we don't get the verbose CEREG: response which contains the RAT, even though we have a valid RSSI value, we error out of converting the RSSI into a proper dB value and return RSSI=1 error case.

Solution:

Unconditionally issue AT+CEREG=2 for LTE (etc.. for 3G/3G) upon registration
This has been fixed in v1.0.1 here: https://github.com/particle-iot/device-os/blob/release/v1.0.1/hal/src/electron/modem/mdm_hal.cpp#L1025-L1045

Other causes of RSSI=1

You still may temporarily see RSSI=1 while you have no cellular signal. Right now the Cellular.API() will return 1 for most most cases (AT timeout or the modem is returning 99 for RSSI). It will return 0 if Cellular.ready() is false, but should return 2 if the modem is returning 99 for RSSI (this needs to be fixed still but it shouldn't cause any problems). If AT commands are failing due to a bug where AT+USOST is used while there is no signal, the Cellular.RSSI() command will temporarily and legitimately return RSSI=1.

2 Likes