MKR GSM 1400 CHRG LED blinking and stop working after certain time

Hey guys.

I'm using MKR GSM 1400 board for an agro project. I'm getting some values from 2 NPK sensors and sending them to a server. This is done every 30 mins as you can see in the following code:

#include <MKRGSM.h>

const char PINNUMBER[]     = "";
const char GPRS_APN[]      = "";
const char GPRS_LOGIN[]    = "";
const char GPRS_PASSWORD[] = "";

GSMClient client;
GPRS gprs;
GSM gsmAccess;

char server[] = "<server>";
char path[] = "<path>";
int port = <port>;

#define RE 5
#define DE 4

//sixIn
const byte moisSixIn[]     = {0x03, 0x03, 0x00, 0x12 ,0x00, 0x01, 0x25, 0xED};
const byte nitroSixIn[]    = {0x03, 0x03, 0x00, 0x1E, 0x00, 0x01, 0xE5, 0xEE};
const byte econSixIn[]     = {0x03, 0x03, 0x00, 0x15, 0x00, 0x01, 0x94, 0x2C};
const byte phSixIn[]       = {0x03, 0x03, 0x00, 0x06, 0x00, 0x01, 0x65, 0xE9};
const byte phosSixIn[]     = {0x03, 0x03, 0x00, 0x1F, 0x00, 0x01, 0xB4, 0x2E};
const byte potaSixIn[]     = {0x03, 0x03, 0x00, 0x20, 0x00, 0x01, 0x84, 0x22};

const byte moisTwelveIn[]  = {0x01, 0x03, 0x00, 0x12, 0x00, 0x01, 0x24, 0x0F};
const byte econTwelveIn[]  = {0x01, 0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xCE};
const byte phTwelveIn[]    = {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0b};
const byte nitroTwelveIn[] = {0x01, 0x03, 0x00, 0x1E, 0x00, 0x01, 0xE4, 0x0C};
const byte phosTwelveIn[]  = {0x01, 0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc};
const byte potaTwelveIn[]  = {0x01, 0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0};

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);

  //while (!Serial) {
    //; // wait for serial port to connect. Needed for native USB port only
  //}

  Serial.println("Starting Arduino web client.");

  bool connected = false;

  while (!connected) {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
      connected = true;
      Serial.println("Connnected to network");

    } else {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  // put RS-485 into receive mode
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  delay(3000);
}

void loop() {
  // SIX INCHES
  Serial.println("SEIS PULGADAS: ");

  float moisture6 = getValue(moisSixIn) / 10;
  delay(500);
  Serial.print("Humedad 6 en decimal: ");
  Serial.println(moisture6);

  float ph6 = getValue(phSixIn) / 100;
  delay(500);
  Serial.print("Ph 6 en decimal: ");
  Serial.println(ph6);

  uint16_t ec6 = getValue(econSixIn);
  delay(500);
  Serial.print("EC 6 en decimal: ");
  Serial.println(ec6);

  uint16_t nitro6 = getValue(nitroSixIn);
  delay(500);
  Serial.print("Nitro 6 en decimal: ");
  Serial.println(nitro6);

  uint16_t phos6 = getValue(phosSixIn);
  delay(500);
  Serial.print("Fosforo 6 en decimal: ");
  Serial.println(phos6);

  uint16_t pota6 = getValue(potaSixIn);
  delay(500);
  Serial.print("Potasio 6 en decimal: ");
  Serial.println(pota6);

  // TWELVE INCHES
  Serial.println("DOCE PULGADAS: ");

  float moisture12 = getValue(moisTwelveIn) / 10;
  delay(500);
  Serial.print("Humedad 12 en decimal: ");
  Serial.println(moisture12);

  float ph12 = getValue(phTwelveIn) / 100;
  delay(500);
  Serial.print("Ph 12 en decimal: ");
  Serial.println(ph12);

  uint16_t ec12 = getValue(econTwelveIn);
  delay(500);
  Serial.print("EC 12 en decimal: ");
  Serial.println(ec12);

  uint16_t nitro12 = getValue(nitroTwelveIn);
  delay(500);
  Serial.print("Nitro 12 en decimal: ");
  Serial.println(nitro12);

  uint16_t phos12 = getValue(phosTwelveIn);
  delay(500);
  Serial.print("Fosforo 12 en decimal: ");
  Serial.println(phos12);

  uint16_t pota12 = getValue(potaTwelveIn);
  delay(500);
  Serial.print("Potasio 12 en decimal: ");
  Serial.println(pota12);

  performRequest(
    moisture6,
    ph6,
    ec6,
    nitro6,
    phos6,
    pota6,
    moisture12,
    ph12,
    ec12,
    nitro12,
    phos12,
    pota12
  );
  // Declarar el tiempo de cada iteración en milisegundos
  // 1 minute
  delay(5000);
}

void performRequest(
  float moisture6,
  float ph6,
  uint16_t ec6,
  uint16_t nitro6,
  uint16_t phos6,
  uint16_t pota6,
  float moisture12,
  float ph12,
  uint16_t ec12,
  uint16_t nitro12,
  uint16_t phos12,
  uint16_t pota12
) {
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, port)) {
    Serial.println("connected");

    String data = "moisture6=" + String(moisture6) +
                "&ph6=" + String(ph6) +
                "&ec6=" + String(ec6) +
                "&nitro6=" + String(nitro6) +
                "&phos6=" + String(phos6) +
                "&pota6=" + String(pota6) +
                "&moisture12=" + String(moisture12) +
                "&ph12=" + String(ph12) +
                "&ec12=" + String(ec12) +
                "&nitro12=" + String(nitro12) +
                "&phos12=" + String(phos12) +
                "&deviceId=" + "<id>" +
                "&pota12=" + String(pota12);

    // Make a HTTP request:
    client.print("POST ");
    client.print(path);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");
    client.println(data.length());
    client.println();
    client.print(data);

    // Read and print the response from the server
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.print(c);
      }
    }

    client.stop();
    Serial.println("disconnected");
  } else {
    Serial.println("connection failed");
  }
}

uint16_t getValue(const byte* command) {
  uint16_t values[7];

  Serial1.flush();

  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(1);

  for (uint8_t i = 0; i < 8; i++) Serial1.write(command[i]);

  Serial1.flush();

  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  delay(200);

  for (byte i = 0; i < 7; i++) {
    values[i] = Serial1.read();
  }

  byte highByte = values[3];
  byte lowByte = values[4];
  uint16_t value  = (highByte << 8) | lowByte;

  return value;
}

For some reason, everything works fine for 3 or 4 days and then it stops sending data. Everytime we check the CHRG orange led is blinking. It's solved by connecting and disconnecting it.

I've seen a lot of posts here but none of them have worked for me. Do you have any idea what could be happening? We're using a 5V usb port to charge the arduino connected to a charger controller, which receives energy from a battery which is also charged by a solar panel.

It's important to mention this happens during the day and night, it doesn't matter.

Hi,
we also had problems with this. It has a very simple solution - you need to connect Lithium battery to board's white connector next to the AREF pin (for example https://www.amazon.com/gp/product/B0BXCF8XF1/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&th=1), it just has to have PH2.0mm JST Connector and 2000+ mAh. First, connect battery, then connect USB, when disconnecting, first unplug USB.

To explain: on-board modem is very sensitive to stability of power source, and it also has to be able to provide at least 2A in peaks. That could be a problem with some charging controllers and even a bad cable quality can be a part of the problem. So, the board is prepared to be powered from directly connected Lithium battery in conjunction with 5V source (don't worry, charging IC will take care of everything) and it seems it is here for this purpose, although official store and sheets does not mention it (I also found out on the forum). This UBLOX modem has a very weird logic, so when it detects there is not enough power to connect to GSM, it will stop trying and will hang forever (and effectively block the entire board) until manually restarted. Connecting the battery should solve this in 99% cases where signal is strong enough to make the first connection, some locations with very bad signal stability could still be tricky.

Hey, thanks for responding. I'll try this and bring the update once I implement it.