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);
}
}
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
log.txt