BC95-g +CSQ:99,99

Hello everyone,

I hope this message finds you well. I’m currently facing a puzzling issue with my NB-IoT project and I’m hoping someone here could provide some guidance. I’ve been working with a Dragino shield for NB-IoT, and I derived my code from the example available at this link: https://github.com/dragino/NB-IoT/blob/master/NB-IoT%20Shield/examples/nbiot_testing1/nbiot_testing.ino

Initially, I was able to configure the code in a way that I could retrieve data from the serial port using commands like “+CSQ18” and “+CEREG:0,5”. However, after making some modifications (or perhaps mistakes), I’ve encountered an unexpected change in the serial output, which now displays “+CSQ_99” instead. My understanding of this field is limited, and I find myself quite lost at the moment.

To provide more context, I’m using an NB-IoT SIM card from the company 1nce, and my objective is to establish a connection with the “mqtt.mydevices.com” server.

I would greatly appreciate any insights you can offer regarding the potential causes of this issue and any recommendations for resolving it.

Thank you in advance for your assistance!

#include <SoftwareSerial.h>

const int timer = 15000; //timer, default: six minites;
/define Serial port*/
const byte rxpin = 10; //Software Serial port
const byte txpin = 11;

const char server[] = “180.101.147.115”; //CDP server of China Telecom
const int port = 5683; //server port

const char udpserver[] = “120.78.138.177”; // UDP server of dragino

static char retmcu[256] = {‘\0’}; //save the mcu return message for AT Command

static byte reboot = 0;

static char IMEI[16] = {‘\0’};

#define MAXLEN 256 // MAX Payload length

#define CHARLEN 32

#define BAUDRATE 9600 //define the baud is 9600bps/s

void mcu_init(); //CPU初始化

int mcu_at_nmgs(int, char *);

void send_data_udp(int, char *);

void read_downstream();

char *mcu_get_imei(char *);

SoftwareSerial bc95_serial(rxpin, txpin); // RX TX
/**************************************************************************************

  • funciton name :setup()

  • parameter :NONE

  • return value :NONE

  • effect :initialize Arduino’s function of setu

  • data :2018/4/16
    ***/
    void setup() { //set the data rate for the Serial port
    Serial.begin(BAUDRATE); // Use Serial Port for debug(config the baud of uart is 9600bps/s)
    bc95_serial.begin(BAUDRATE); //config module of bc95 baud of uart is 9600bps/s too.
    mcu_init(); //module were initialized.
    delay(1000); //Arduino delay 1 second
    }
    /

  • funciton name :loop()

  • parameter :NONE

  • return value :NONE

  • effect :NB-IoT init and send for data to platform

  • data :2018/4/16
    ***/
    void loop() {
    char temp[] = “Send a UDP datagram containing length bytes of data”; //the array was defined ,the data was straged on it
    Serial.println(F(“Send a message use UDP Protocol”)); //computer will printed to char string
    send_data_udp(strlen(temp), temp); //send to udp server
    delay(1000); //delay 1 second
    Serial.println(F(“Send a message use CoAP Protocol”)); //computer will printed to char string
    mcu_at_nmgs(3, “020103”); //send message to CoAP server, for testing
    delay(timer); //delay(1500)
    read_downstream();
    delay(1000);
    }
    /

  • funciton name :bc95_serial_read()

  • parameter :NONE

  • return value :NONE

  • effect :data was straged in retmcu array

  • data :2018/4/16
    *****************************************************************************************/
    void bc95_serial_read()
    {
    int i = 0;

    memset(retmcu, 0, sizeof(retmcu));//reference c language lib menset
    //array is cleaned in here
    bc95_serial.flush(); //Waits for the transmission of outgoing serial data to complete.

    delay(1500); //Waits for respones from server

    while(bc95_serial.available() && i < sizeof(retmcu) - 1) {
    retmcu[i] = bc95_serial.read();//read return’s value and strage in this array
    i++;
    }

    retmcu[i] = ‘\0’; //

    Serial.println(retmcu); //for debug
    }
    /**************************************************************************************

  • funciton name :bc95_serial_clearbuf()

  • parameter :NONE

  • return value :NONE

  • effect :clear the buffer

  • data :2018/4/16
    *****************************************************************************************/
    void bc95_serial_clearbuf()
    {
    bc95_serial.flush();

    while(bc95_serial.available()) {
    bc95_serial.read();
    }
    }
    /**************************************************************************************

  • funciton name :str2hex()

  • parameter :NONE

  • return value :NONE

  • effect :conver strings to ascii code

  • data :2018/4/16
    *****************************************************************************************/
    void str2hex(char *hexstr, int hexlen, char *str, int strlen)
    {
    int i;
    char tmp1[4] = {‘\0’};
    for (i = 0; i < strlen - 1; i++) {
    sprintf(tmp1, “%x”, str[i]);
    strncat(hexstr, tmp1, hexlen);
    }
    }

/**************************************************************************************

  • funciton name :mcu_at_nrb()
  • parameter :NONE
  • return value :NONE
  • effect :Sent the AT command
  • data :2018/4/16
    ***/
    void mcu_at_nrb()
    {
    bc95_serial_clearbuf(); //clear the buffer
    Serial.println(F(“Reboot BC95”)); //
    bc95_serial.println(F(“AT+NRB”)); //send AT+NRB command to NB-IoT,this command is that module will be reboot
    }
    /
  • funciton name :mcu_at_ok()
  • parameter :NONE
  • return value :NONE
  • effect :Sent the AT command
  • data :2018/4/16
    *****************************************************************************************/
    void mcu_at_ok()
    {
    while(1) {
    bc95_serial_clearbuf(); //clear the buffer
    bc95_serial.println(F(“AT”)); //send "AT"command to NB-IoT
    bc95_serial_read(); //read the return value
    if (strstr(retmcu, “OK”) != NULL) { //if return value is “OK” than program delay 1second jump out loop
    delay(1000);
    break;
    }
    }
    }

/**************************************************************************************

  • funciton name :mcu_get_cimi

  • parameter :NONE

  • return value :NONE

  • effect :Sent the AT+CIMI command

  • data :2018/4/16
    ***/
    void mcu_get_cimi()
    {
    while(1) {
    bc95_serial_clearbuf(); //flush bc95_serial
    Serial.println(F(“AT+CIMI”)); //
    bc95_serial.println(F(“AT+CIMI”)); //send AT+CIMI command to NB-IoT module
    bc95_serial_read(); //read the return value
    break; //jump out of loop
    }
    }
    /

  • funciton name :mcu_get_imei

  • parameter :*char

  • return value :*char

  • effect :gain the IMEI code

  • data :2018/4/16
    *****************************************************************************************/
    char *mcu_get_imei(char *imei)
    {
    int i;
    char *pt; //this pointer in order to recevied the IMEI code take in imei array

    bc95_serial_clearbuf(); //clear the buffer
    Serial.println(F(“AT+CGSN=1”)); //
    bc95_serial.println(F(“AT+CGSN=1”)); //send the "AT+CGSN=1"command,then the return value is IMEI code
    bc95_serial_read(); //read return code

    //judge if have return value of IMEI code
    if (strstr(retmcu, “+CGSN”) != NULL) { /* respones format: +CGSN:86370303110??? */
    pt = strrchr(retmcu, ‘:’); //
    for(i = 0; i < sizeof(IMEI); i++) {
    imei[i] = pt[i+1]; //store the IMEI code to imei array.
    }
    return imei; //return the imei array
    }

    return NULL; //or return NULL
    }

/**************************************************************************************

  • funciton name :mcu_at_nband()
  • parameter :NONE
  • return value :NONE
  • effect :Arduino sent"AT +NBAND"to NB-IoT,we choose 850Mhz working frequency
  • data :2018/4/16
    ***/
    void mcu_at_nband()
    {
    while(1) {
    bc95_serial_clearbuf(); //clean the buffer to NB-IoT
    Serial.println(F(“AT+NBAND?”)); //Arduino print “AT+NBAND?” char string to computer
    bc95_serial.println(F(“AT+NBAND?”)); //Arduino send “AT+NBAND?“command to NB-IoT,in order to looking the module work in state
    bc95_serial_read(); //read the return value
    if(strstr(retmcu, “+NBAND:5”) != NULL) { //Read the retmcu array,Arduino start judge the value appear nbnber"5”
    break; //if the value is number"5”,NB-IoT working frequency is 850Mhz,jump out of the loop.
    } else {
    Serial.println(F(“AT+NBAND=5”)); //if the return value isn’t number"5",afterward,Arduino sent "AT+NBABD=5"command to NB-Iot module.
    bc95_serial.println(F(“AT+NBAND=5”)); // AT+NBABD=5 command is chose the mode that NB-IoT working frequency is 850Mhz
    reboot = 1; //reboot laber bit assignment is “1”.
    break; //program jumps out of the loop
    }
    }
    }
    /
  • funciton name : mcu_at_cgdcont()
  • parameter :NONE
  • return value :NONE
  • effect :Define a PDP Context * notice:
  • data :2018/4/16
    ***/
    void mcu_at_cgdcont()
    {
    bc95_serial_clearbuf();
    Serial.println(F(“AT+CGDCONT=1,IP,CTNB”));
    bc95_serial.println(F(“AT+CGDCONT=1,"IP","CTNB"”));
    delay(1000);
    bc95_serial_clearbuf();
    Serial.println(F(“AT+CGDCONT?”));
    bc95_serial.println(F(“AT+CGDCONT?”));
    bc95_serial_read();
    }
    /
  • funciton name :mcu_at_nconfig()
  • parameter :NONE
  • return value :NONE
  • effect :send AT+NCONFIG command,look for NB-IoT message of config
  • data :2018/4/16
    ***/
    void mcu_at_nconfig()
    {
    while(1) {
    bc95_serial_clearbuf(); //clear the buffer
    Serial.println(F(“AT+NCONFIG?”)); //
    bc95_serial.println(F(“AT+NCONFIG?”)); //send “AT+NCONFIG"command
    bc95_serial_read(); //return the value
    if(strstr(retmcu, “+NCONFIG:AUTOCONNECT,FALSE”) != NULL) { //if return value isn’t”+NCONFIG:AUTOCONNECT,FALSE",this isn’t auto look for network…
    Serial.println(F(“AT+NCONFIG=AUTOCONNECT,TRUE”)); //
    bc95_serial.println(F(“AT+NCONFIG=AUTOCONNECT,TRUE”)); //then send for"AT+NCONFIG=AUTOCONNECT,TRUE"command to NB-IoT
    reboot = 1; //1reboot module laber is “1”
    break; //break the while(1)
    } else if (strstr(retmcu, “+NCONFIG:AUTOCONNECT,TRUE”) != NULL) {//
    break; //
    } else { //this is else if wait for appear return is ture
    //Do Nothing
    }
    }
    }
    /
  • funciton name :mcu_at_csq()
  • parameter :NONE
  • return value :NONE
  • effect :send "AT+CSQ"command,look for singal strengh
  • data :2018/4/16
    ***/
    void mcu_at_csq()
    {
    while(1) {
    bc95_serial_clearbuf();
    Serial.println(F(“AT+CSQ”));
    bc95_serial.println(F(“AT+CSQ”));
    bc95_serial_read();
    if(strstr(retmcu, “+CSQ:99,99”) != NULL) { // res 99 is nosignal
    continue;
    } else if (strstr(retmcu, “+CSQ:”) != NULL) {
    break;
    } else {
    // Do Nothing
    }
    }
    }
    /
  • funciton name :mcu_at_cgatt()
  • parameter :NONE
  • return value :NONE
  • effect :send "AT+CGATT"command,detect network if activate
  • data :2018/4/16
    ***/
    void mcu_at_cgatt()
    {
    while(1)
    {
    bc95_serial_clearbuf(); //clear the send buffer
    Serial.println(F(“AT+CGATT?”));
    bc95_serial.println(F(“AT+CGATT?”)); //"AT+CGATT"command
    bc95_serial_read(); //return the value
    if(strstr(retmcu, “+CGATT:1”) != NULL) { //return value 1:active,0:disavtive
    break; //active break while
    }
    }
    }
    /
  • funciton name :mcu_at_cfun()
  • parameter :NONE
  • return value :NONE
  • effect :send "AT+CFUN"command,enable Receive and send
  • data :2018/4/16
    ***/
    void mcu_at_cfun()
    {
    while(1) {
    bc95_serial_clearbuf(); //clear the buffer
    Serial.println(F(“AT+CFUN?”));
    bc95_serial.println(F(“AT+CFUN?”)); //send “AT+CFUN"command to NB-IoT module
    bc95_serial_read(); //read return value
    if(strstr(retmcu, “+CFUN:1”) != NULL) { //if return value is"1”,reprense NB-IoT enable receive and send port,at the moment break the while
    break;
    } else { //or wait for return is"1"
    //Do Nothing
    }
    }
    }
    /
  • funciton name :mcu_at_cereg()
  • parameter :NONE
  • return value :NONE
  • effect :send "AT+CEREG"command,look for EPS network is register state
  • data :2018/4/16
    ***/
    void mcu_at_cereg()
    {
    while(1)
    {
    bc95_serial_clearbuf(); //clear the buffer
    Serial.println(F(“AT+CEREG?”));
    bc95_serial.println(F(“AT+CEREG?”)); //send "AT+CEREG?"command to NB-IoT
    bc95_serial_read();
    if(strstr(retmcu, “+CEREG:0,1”) != NULL) { // res +CEREG:n,stat , stat=2 indicate not registered
    break;
    }
    if(strstr(retmcu, “+CEREG:5,1”) != NULL) {
    break;
    }
    }
    }
    /
  • funciton name :mcu_at_cscon()
  • parameter :NONE
  • return value :NONE
  • effect :send "AT+CSCON"command
  • data :2018/4/16
    *****************************************************************************************/
    void mcu_at_cscon()
    {
    while(1)
    {
    bc95_serial_clearbuf();
    Serial.println(F(“AT+CSCON?”));
    bc95_serial.println(F(“AT+CSCON?”));
    bc95_serial_read();
    if(strstr(retmcu, “+CSCON:0,1”) != NULL) { //res +CSCON:n,mode , if mode=1 connected, 0 idle
    break;
    }
    }
    }

/**************************************************************************************

  • funciton name :mcu_at_ncdp()
  • parameter :NONE
  • return value :NONE
  • effect :send "AT+NCDP"command,config and look for CDP server
  • data :2018/4/16
    *************************/
    void mcu_at_ncdp()
    {
    while(1) {
    bc95_serial_clearbuf();
    Serial.println(F(“AT+NCDP?”));
    bc95_serial.println(F(“AT+NCDP?”));
    bc95_serial_read(); //query the "AT+NCDP"command,read return value
    if(strstr(retmcu, server) != NULL) //return value is not NULL,break the while
    break;
    else {
    bc95_serial_clearbuf();
    Serial.println(F(“AT+CFUN=0”));
    bc95_serial.println(F(“AT+CFUN=0”));
    bc95_serial_read(); //send "AT+CFUN=0"command and read return value
    if(strstr(retmcu, “OK”) != NULL) { //
    char cmd[32] = {‘\0’};
    snprintf(cmd, sizeof(cmd), “AT+NCDP=%s,%d”,server, port);
    bc95_serial.println(cmd);
    bc95_serial_read();
    if(strstr(retmcu, “OK”) != NULL) { //
    bc95_serial.println(F(“AT+CFUN=1”));
    delay(500);
    break;
    }
    }
    }
    }
    }
    /
  • desc: send a message from the terminal to network via connect
  • device platform server. (CDP)
  • ret: return 0 if send message success
    *************************************************************** */
    int mcu_at_nmgs(int len, char *data)
    {
    char cmd[256] = {‘\0’};
    snprintf(cmd, sizeof(cmd), “AT+NMGS=%d,%s”, len, data);
    bc95_serial_clearbuf();
    Serial.println(cmd);
    bc95_serial.println(cmd);
    delay(1000); //wait 1 sencond
    bc95_serial_read();
    if(strstr(retmcu, “OK”) != NULL) {
    return 0;
    }
    return 1;
    }

/****************************************************************

  • desc: Queries the status of downstream messages received from
  •   the CDP server
    
  • Res: BUFFERED=, RECENIVED=, DROPPED=
  •  +CME ERROR:<err>
    

*************************************************************** */
void mcu_at_nqmgr()
{
bc95_serial_clearbuf();
Serial.println(F(“AT+NQMGR”));
bc95_serial.println(F(“AT+NQMGR”));
bc95_serial_read();
}

/****************************************************************

  • desc: Queries the status of downstream messages received from
  •   the CDP server
    
  • note:

*************************************************************** */

void read_downstream()
{
int i;
char *sp, buf[8];

mcu_at_nqmgr();

if ((strstr(retmcu, "BUFFERED=")) != NULL) {

    sp = strchr(retmcu, '=');

    for (i = 0; sp[i] != ',', i < 8; i++) {
        buf[i] = sp[i + 1];
    }

    buf[i] = '\0';

    if (atoi(buf) > 0) 
        mcu_at_nmgr();
}

}
/****************************************************************

  • desc: Queries the status of the upstream messages
  •   sent to the CDP server
    
  • note:
  • Res: PENDING=, SENT=, ERROR=

*************************************************************** */
void mcu_at_nqmgs()
{
bc95_serial_clearbuf();
Serial.println(F(“AT+NQMGS”));
bc95_serial.println(F(“AT+NQMGS”));
bc95_serial_read();
}

/****************************************************************

  • desc: return the oldest buffered message and deletes from buffer
  • note: if new message indications(AT+NNMI)are turn on then received
  • messages will not be available via this command

*************************************************************** */
void mcu_at_nmgr()
{
bc95_serial_clearbuf();
Serial.println(F(“AT+NMGR”));
bc95_serial.println(F(“AT+NMGR”));
bc95_serial_read();
}

/****************************************************************

  • desc: create udp socket
    • AT+NSOCR=,,[,]
    • udp type:DGRAM, protocol:17, receive control default is 1 message will be receive
  • note: if a socket has already created, will fail if requested a second time
    *************************************************************** */
    void mcu_at_nsocr()
    {
    bc95_serial_clearbuf();
    Serial.println(F(“AT+NSOCR=DGRAM,17,5999,1”));
    bc95_serial.println(F(“AT+NSOCR=DGRAM,17,5999,1”));
    bc95_serial_read();
    }

/****************************************************************

  • desc: send data to udp server

  • AT+NSOST=socket,remote_addr,remote_port, length, data

  • socket: number return by AT+NSOCR, 0 as default
    *************************************************************** */
    void mcu_at_nsost(int len, char *data)
    {
    int i;
    char imeihex[32] = {‘\0’};
    char datahex[MAXLEN] = {‘\0’};

    str2hex(imeihex, sizeof(imeihex), IMEI, strlen(IMEI));

    str2hex(datahex, sizeof(datahex), data, len);

    bc95_serial_clearbuf();
    snprintf(retmcu, sizeof(retmcu), “AT+NSOST=0,%s,%d,%d,%s3D%s”, udpserver, port, len + strlen(IMEI) - 1, datahex, imeihex);
    Serial.println(retmcu);
    bc95_serial.println(retmcu);
    bc95_serial_read();
    }

/****************************************************************

  • desc: read the req_length characters of data from socket

*************************************************************** */
void mcu_at_nsorf()
{
bc95_serial_clearbuf();
Serial.println(F(“AT+NSORF=0,512”)); // read 512 characters form socket 0
bc95_serial.println(F(“AT+NSORF=0,512”)); // read 512 characters form socket 0
bc95_serial_read();
if(strstr(retmcu, “+NSONMI:”) != NULL) { // +NSONMI: has message
bc95_serial.println(F(“AT+NSORF=0,512”));
bc95_serial_read();
}
}

/**************************************************************************************

  • funciton name :mcu_at_cgpaddr()

  • parameter :*ip

  • return value :NONE

  • effect :send "AT+CGPADDR"command,display the PDP addr

  • data :2018/4/16
    ***/
    void mcu_at_cgpaddr()
    {
    bc95_serial_clearbuf();
    Serial.println(F(“AT+CGPADDR”));
    bc95_serial.println(F(“AT+CGPADDR”));
    bc95_serial_read();
    }
    /

  • funciton name :mcu_at_nping()

  • parameter :*ip

  • return value :NONE

  • effect :ping

  • data :2018/4/16
    ******/
    void mcu_at_nping(char ip)
    {
    char cmd[64] = {‘\0’};
    snprintf(cmd, sizeof(cmd), “AT+NPING=%s”, ip); //函数原型为int snprintf(char str, size_t size, const char format, …)
    bc95_serial_clearbuf();
    Serial.println(cmd);
    bc95_serial.println(cmd);
    }
    /

  • funciton name :mcu_init()

  • parameter :NONE

  • return value :NONE

  • effect :init the NB-IoT module

  • data :2018/4/16
    *****************************************************************************************/
    void mcu_init()
    {
    mcu_at_nband(); //choose the NB-IoT working band
    mcu_at_nconfig(); //config auto look for network

    if (reboot) {
    reboot = 0; //
    mcu_at_nrb(); //reboot the NB-IoT module
    delay(5000); //delay 5 second
    }

    if (NULL == mcu_get_imei(IMEI))//if return value is null,Arduino Send char string to computer port
    Serial.println(F(“IMEI = NULL”));
    else {
    Serial.print(F(“IMEI=”));
    Serial.println(IMEI); //else Arduino send IMEI code to computer port
    }

    mcu_at_ncdp(); //query IP addr
    mcu_at_csq(); //query signal if strengh
    mcu_at_cgatt(); //Send “AT+CGATT” command
    mcu_at_cereg(); //query network register satues is success,"1"resprent success
    mcu_at_cgdcont(); //quest work statues,second parameter is return statues,“1” represent is connet
    mcu_at_cgpaddr();
    mcu_at_nsocr(); // Greate a SOcket
    }

/****************************************************************

  • desc :

*************************************************************** */
void send_data_udp(int len, char *data)
{
mcu_at_nsost(len, data);
}

/****************************************************************

  • desc :

*************************************************************** */
void mcu_rec_data()
{
mcu_at_nsorf();
}

AT+NBAND?
⸮⸮r 9⸮
+NBAND:8

OK

AT+NCONFIG?
⸮⸮NCONFIG?
+NCONFIG:AUTOCONNECT,TRUE
+NCONFIG:CR_0354_0338_SC
AT+CGSN=1
⸮⸮M9⸮1
+CGSN:866416042445354

OK

IMEI=866416042445354
⸮⸮M9⸮1
+CGSN:866416042445354

OK

AT+NCDP?
⸮⸮r
A⸮
+NCDP:180.101.147.115,5683

OK

AT+CSQ
⸮⸮ME5
+CSQ:99,99

OK

AT+CSQ
⸮⸮CSQ
+CSQ:99,99

OK

Quectel_UEMonitor操作指导与参考(CN&EN)_BC28&BC95&BC68&BC35G&BC95G.pdf (1.3 MB)
Please refer to the document capture debug log, I have sent the tool to you

The EU monitor detects COM port 7 but reports ‘Unable to open COM7.’ I have used an FT232 module to connect the Quectel module to the PC

I have sent you the driver, please install and try again

The Dragino IO Shield Ver1.2 has a button. I’ve managed to somehow get the Net LED on the shield to light up again, which I assume is a good thing because no matter what I did before, that LED was always off. When I connect the module with the Net LED off to the EU monitor, I receive the following message.

If I press the button while connected, led Net turns green, I get the following messages





I hope you excuse me for not readings all the replies… but …
I’ve had similar issues.
1/ pop out the SIM card and put it back in.
2/ check your APN ( AT+CGDCONT?) (you have to reset the modem after changing this)

The reason I say this is CSQ is a bit confusing, 99 is also reported in the network refuses a connection. I’ve had that happen when it couldn’t read the SIM after a few days, or when given the wrong APN etc.

Simon

Debug Log.Zip (138.4 KB)

Good news, I’ve got the debug log
SimonPeacock, I’ll also do my best to follow your instructions when support provides a solution.

Importing logs for parsing is very bad,so,I don’t have a better way to help you solve it

I assume the issue is that you can’t see the names of the error messages, but in my eumonitor, the names of the error messages do appear. Is there anything I can do? The BC95 module is part of my final degree project

I want to debug it remotely

I’ve downloaded a remote control application called Sunloging Remote. Is this the app I should be using? What steps should I take?

When will you allow me to perform remote debugging and require you to provide the sunlogin remote account and password?