arduino-libraries / MKRGSM

GNU Lesser General Public License v2.1
54 stars 51 forks source link

MKR1400 stops communicating after some time #134

Closed StefanBerchtold closed 3 years ago

StefanBerchtold commented 3 years ago

Hello,

I am using the MKR1400 board for a project (water level monitoring) and have some problems with the MKRGSM library. The main idea is to measure the water level and send a SMS when the water level goes below a certain limit. Sending and receiving SMS is working fine. But after some while the program stucks at SMS.available().

So I did some investigations, removed all unimportant parts and added the functions GSM.isAccessAlive() and GSM.ready() in the loop. And after some time, they are returning both 0. Regarding the ready() function, the return value is defined as "returns 0 if last command is still executing". But the last command: AT+CMGL="REC UNREAD" is answered with OK. From then on, no sent or received AT command is shown in the serial output.

Does anyone have an idea what happens or what can I do to investigate this problem further?

My board is powered with 2000 mAh battery (also tested with power supply unit), MKRGSM 1.5.0 installed

#include <Arduino.h>
#include <MKRGSM.h>
#include <ArduinoLowPower.h>

/* Defines *******************************************************************/
#define PRINT_DEBUG(_txt)   do{if(debug_mode) Serial.print(_txt);}while(0); // Print debug info
#define PRINT(_txt)         do{Serial.print(_txt);}while(0); // Print info
// Timings
#define TIMER_SLEEP         3000    // [ms] Sleep time: only 3s for testing
// Board pins
#define PIN_SERVICE_EN      2       // Service enable input
#define PIN_LED_BUSY        3       // Busy status led
#define PIN_DEBUG_MODE      7       // Debug enable input
// GSM
#define GSM_NUMBER_SIZE     20      // Max. size of phone number in bytes

/* GSM definitions ***********************************************************/
const char PINNUMBER[] = "xxxx";        // SIM card pin number
String gsm_nr_service("+43xxxxxxxxxx"); // Service number

/* Global variables **********************************************************/
bool service_mode;
bool debug_mode;
bool debug_mode_old;
GSM Gsm(true);
GSM_SMS Sms;
unsigned int down_cnt = 0;

/*****************************************************************************
 * Switch on debug LED
 *****************************************************************************/
void set_debug_led()
{
    digitalWrite(LED_BUILTIN, HIGH);
}

/*****************************************************************************
 * Switch off debug LED
 *****************************************************************************/
void clear_debug_led()
{
    digitalWrite(LED_BUILTIN, LOW);
}

/*****************************************************************************
 * Switch on busy LED
 *****************************************************************************/
void set_busy_led()
{
    digitalWrite(PIN_LED_BUSY, HIGH);
}

/*****************************************************************************
 * Switch off busy LED
 *****************************************************************************/
void clear_busy_led()
{
    digitalWrite(PIN_LED_BUSY, LOW);
}

/*****************************************************************************
 * Check if debug mode is enabled
 *****************************************************************************/
bool get_debug_mode()
{
    return digitalRead(PIN_DEBUG_MODE) == HIGH;
}

/*****************************************************************************
 * Check if service mode is enabled
 *****************************************************************************/
bool get_service_mode()
{
    return digitalRead(PIN_SERVICE_EN) == HIGH;
}

/*****************************************************************************
 * Pin initialization
 *****************************************************************************/
void pin_init()
{
    pinMode(PIN_LED_BUSY, OUTPUT);
    pinMode(PIN_DEBUG_MODE, INPUT_PULLDOWN);
}

/*****************************************************************************
 * Serial interface (USB) initialization
 *****************************************************************************/
bool serial_init()
{
    // initialize serial communications and wait for port to open:
    Serial.begin(9600);
    while (!Serial) {
        // Wait for serial port to connect.
        // To avoid being stuck in an endless loop when debug mode is
        // activated but no cable is connected, the input is checked
        // cyclically and debug mode is deactivated again if necessary.
        debug_mode = get_debug_mode();
        if (!debug_mode)
            return false;
        delay(200);
    }
    return true;
}

/*****************************************************************************
 * GSM module: initialization
 *****************************************************************************/
void gsm_init()
{
    PRINT_DEBUG("Start GSM module ...\n")

    // Connection state
    bool connected = false;

    // Start GSM connection
    while (!connected)
    {
        if (Gsm.begin(PINNUMBER) == GSM_READY)
        {
            connected = true;
        }
        else
        {
            PRINT_DEBUG("Connection failed. Trying again ...\n")
            delay(500);
        }
    }

    Gsm.lowPowerMode();
    Gsm.setTimeout(60000);
}

/*****************************************************************************
 * Process the debug mode
 *****************************************************************************/
void process_debug_mode()
{
    // Save old debug mode state
    debug_mode_old = debug_mode;
    // Get current debug mode state
    debug_mode = get_debug_mode();
    if (debug_mode)
    {
        set_debug_led();
        if (!debug_mode_old)
        {
            // Only once when activating debug mode
            // Attach USB device after sleep mode
            USBDevice.attach();
            delay(1000);
            // Start serial connection
            if (!serial_init())
            {
                // Rollback and deactivate debug mode
                // TODO: PC recognizes the USB port anyway ...
                // Serial.end();
                USBDevice.detach();
                clear_debug_led();
                return;
            }
        }
    }
    else
    {
        clear_debug_led();
    }
}

/*****************************************************************************
 * GSM module: Reply to incomming SMS
 *****************************************************************************/
void gsm_reply()
{
    String sender_message;
    int ch, alive, ready;
    char number[GSM_NUMBER_SIZE] = {0};

    alive = Gsm.isAccessAlive();
    ready = Gsm.ready();

    if (debug_mode)
    {
        PRINT("GSM access: ")
        PRINT(alive)
        PRINT(", ready: ")
        PRINT(ready)
        PRINT(", down for: ")
    }
    if ((alive != 1) || (ready != 1))
        down_cnt++;

    if (debug_mode)
    {
        PRINT(down_cnt)
        PRINT(" cycle(s)\n")
    }

    // Check if status is ok
    if ((alive != 1) || (ready != 1))
        return;

    // Check if SMS was received
    if (Sms.available() == 0)
        return;

    // Get remote number
    Sms.remoteNumber(number, GSM_NUMBER_SIZE - 1);

    // Read message bytes
    while ((ch = Sms.read()) != -1)
        sender_message += (char) ch;

    if (number[0] != '\0')
    {
        const String sender_number(number);

        if (debug_mode)
        {
            String msg;
            msg += "Message received from: ";
            msg += sender_number;
            msg += "\n";
            msg += sender_message;
            msg += "\n*** END OF MESSAGE ***\n";
            PRINT(msg)
        }

        // Service SMS
        if (sender_number.compareTo(gsm_nr_service) == 0)
        {
            // do nothing for now
        }
    }
    else
    {
        // No remote number available
        String msg;
        PRINT_DEBUG("No remote number available!\n")
        // do nothing for now
    }

    // Delete message from modem memory, can take some time
    PRINT_DEBUG("Delete message ... ")
    Sms.flush();
    PRINT_DEBUG("done\n")
}

/*****************************************************************************
 * Setup function
 *****************************************************************************/
void setup()
{
    pin_init();
    set_busy_led();
    debug_mode_old = debug_mode = get_debug_mode();
    if (debug_mode)
    {
        set_debug_led();
        serial_init();
    }
    gsm_init();
    PRINT_DEBUG("Initialization done!\n"
        "\n****************************************\n")
    clear_busy_led();
}

/*****************************************************************************
 * Loop function
 *****************************************************************************/
void loop()
{
    // Process IOs, service- and debug mode
    set_busy_led();
    process_debug_mode();

    // Answer to incomming SMS
    gsm_reply();
    if (down_cnt > 10)
    {
        // Stop here
        while(true);
    }
    PRINT_DEBUG("\n****************************************\n")
    clear_busy_led();

    if (debug_mode)
    {
        // Just wait to keep serial connection
        delay(TIMER_SLEEP);
    }
    else
    {
        if (debug_mode_old)
        {
            // Only once when leaving debug mode
            USBDevice.detach();
        }
        // Go to sleep mode
        LowPower.sleep(TIMER_SLEEP);
    }
}

log.txt