Can't send SMS fro MKR GSM 1400 stacked onto Connector Carrier

Hi

I've been testing some scenarios and I can conclude the Connector Carrier accepts happily the 12VDC I provide through its input screw pins, converts it into a healthy 5.09VDC to feed into the VIN pin, and that it also extends the board's 5V pin (with only 4.66VDC) and VCC (with just 3,28VDC) pin to the screws too. Those two last coming from the MKR board itself, not the connector carrier buck.

According to https://docs.arduino.cc/learn/electronics/power-pins, when VIN is used, the 5VDC and VCC pins become output only. So doing this https://forum.arduino.cc/t/mkr-connector-carrier-low-connector-voltage-when-using-vin-non-usb-power/703989/5 won't help the way I need.

My issue is that if I feed 12VDC from my 20W power supply into the connector carrier, the SMS are never sent. Usually that means lack of power from the power source, which in this case it is not the reason. If I connect the USB port to my computer or a power adaptor, all SMS are sent. But it should not be that way, because USB in power is disabled when VIN is used according to the documentation.

I also tried simply connecting the USB cord with the charger still attached but unplugged from the socket, and the SMS are sent too. If the issue was that my code needed an USB host to work, the unplugged charger wouldn't be enough.

There is something weird going on here. Feels like the ghost of electronics (not software). But I cannot tell why since the SMS are not coming and the USB console is unavailable at the time of the issue.

Any piece of advice?

Thanks

#undef DEBUG  // If defined it enables debug messages to serial usb. Comment or undef to deactivate DEBUG to console and the console itself.

#include "arduino_secrets.h"
#include <MKRGSM.h>
#include <ArduinoLowPower.h>
#include <RTCZero.h>
#include <Arduino_PMIC.h>  // Toolbox for the chip dealing with power and battery
//#include <Modem.h>         // SARA-U201 GSM modem chip

// Self awareness
const int DEBUG_LEVEL = 2;             // 0 = no debug, 1 = some debug, 2 = deep debug (if not defined the DEBUG tag, this has no effect)
const int sketchUpdateWindow = 10000;  // Tine window to allow sketch updates after boot
bool watchdogFlag = false;             // If the board gets frozen, lets try to prevent bricking and auto-recover failure when possible

// Duty cycle
const int shortLoopPeriod = 600000;                   // Sleep for 600000 miliseconds (10 minutes)
const int longLoopPeriod = 3600000;                   // Sleep for 3600000 miliseconds (60 minutes)
int loopPeriod = shortLoopPeriod;                     // Work period of the board = 600000 miliseconds (10 minutes) by default

// GSM network data
const char SIM_APN[] = SECRET_SIM_APN;
const char SIM_PIN[] = SECRET_OPTIONAL_SIM_PIN;
const char SIM_APN_USERNAME[] = SECRET_OPTIONAL_SIM_APN_USERNAME;
const char SIM_APN_PASSWORD[] = SECRET_OPTIONAL_SIM_APN_PASSWORD;
const char controlPhoneNumber[] = SECRET_CONTROL_PHONE_NUMBER;
const int connectWaitingTimeForGSM = 10000;           // GSM network connect proved slow in Spain, so lets wait 10 seconds instead of 1.
const int maximumLengthSMS = 140;                     // How many char do we want to allow into an SMS or chain of SMSs.

// Incoming water valve pressure sensor pin and attributes
const int incomingPressureSensorPin = A4;             // Analog PIN connector of the board to plug the sensor to
const float incomingPressureSensorMinPressure = 0.0;  // Minimum pressure callibrated with external manometer that can be read by ADC
const float incomingPressureSensorMaxPressure = 5.0;  // Maximum pressure callibrated with external manometer that can be read by ADC
const int incomingPressureSensorMinReading = 102;     // ADC reading of minimum voltage for minimum pressure of the sensor (500mVDC at 0 bar)
const int incomingPressureSensorMaxReading = 921;     // ADC reading of maximum voltage for maximum pressure of the sensor (4500mVDC at 5 bar)

// Power management
volatile unsigned long time_last_battery_interrupt = millis();

// Set up the GSM module
GSM gsmAccess;
GSM_SMS sms;

void setup() {

  //////////////////////////
  // Sketch update window //
  //////////////////////////
  /* 
    It seems the board won't be accepting upload of new scketches if in low power mode.
    So lets wait ten seconds upon board start so there is a chance.
  */

  delay(sketchUpdateWindow);

  //////////////////////////////////////////
  // USB serial port to use for debugging //
  //////////////////////////////////////////

#ifdef DEBUG
  // Initialize the serial communication for debugging
  Serial.begin(9600);
  while (!Serial) {
    ;  // Wait for serial port to connect
  }
#endif

  //////////////////////////////////////
  // Power Management Integrated Chip //
  //////////////////////////////////////
  /*
#ifdef DEBUG
  Serial.println("PMIC initialization about to start.");
#endif

// Available only for MKRGSM1400 and MKRNB1500
#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500)
  // Attach the PMIC IRQ pin
  attachInterrupt(digitalPinToInterrupt(PMIC_IRQ_PIN), batteryInterrupt, FALLING);
#endif

  // Initialize the power management integrated cirtuit that charges and uses the battery
  if (!PMIC.begin()) {
#ifdef DEBUG
    Serial.println("Failed to initialize PMIC!");
#endif
    // while (1); QUESTION TO FUTURE ME: why did the original author of PMIC eample lock the board in an endless loop if failed PMIC?
  }

  // Set the input current limit to 2 A
  if (!PMIC.setInputCurrentLimit(2.0)) {
#ifdef DEBUG
    Serial.println("Error in set input current limit");
#endif
  }

  // Set the overload input voltage to 3.88 V
  if (!PMIC.setInputVoltageLimit(3.88)) {
#ifdef DEBUG
    Serial.println("Error in set input voltage limit");
#endif
  }

  // set the minimum voltage used to feeding the module embed on Board
  if (!PMIC.setMinimumSystemVoltage(3.5)) {
#ifdef DEBUG
    Serial.println("Error in set minimum system volage");
#endif
  }

  // Set the desired charge voltage to 4.11 V
  if (!PMIC.setChargeVoltage(4.2)) {
#ifdef DEBUG
    Serial.println("Error in set charge volage");
#endif
  }

  // Set the charge current 500 mA
  if (!PMIC.setChargeCurrent(0.500)) {
#ifdef DEBUG
    Serial.println("Error in set charge current");
#endif
  }

  // Enable the Charger
  if (!PMIC.enableCharge()) {
#ifdef DEBUG
    Serial.println("Error enabling Charge mode");
#endif
  }

#ifdef DEBUG
  Serial.println("PMIC initialization done!");
#endif
*/
  /////////////////
  // GSM Module  //
  /////////////////
  /*
    SIM has PIN disabled due to undefined incompatibilities.
    We use the constructor without PIN.
  */

  // Start GSM connection
#ifdef DEBUG
  if (DEBUG_LEVEL > 0) { Serial.println("Starting GSM..."); }
#endif
  if (gsmAccess.begin() != GSM_READY) {
#ifdef DEBUG
    if (DEBUG_LEVEL > 1) { Serial.println("Not connected on first attempt!"); }
#endif
    do {
#ifdef DEBUG
      if (DEBUG_LEVEL > 1) { Serial.println("Not connected yet!"); }
#endif
      delay(connectWaitingTimeForGSM);
    } while (gsmAccess.begin() != GSM_READY);
#ifdef DEBUG
    if (DEBUG_LEVEL > 1) { Serial.println("Finally connected!"); }
#endif
  }
#ifdef DEBUG
  if (DEBUG_LEVEL > 0) { Serial.println("GSM initialized."); }
#endif

  ///////////
  // Clock //
  ///////////
  /*
    Now that we have GSM, we can read the time and set it.
  */

  

}

void loop() {
  int incomingPressureSensorValue;
  float incomingPressure;

  // Check for watchdog flag
  if (watchdogFlag) {
    // Perform recovery or error handling here
#ifdef DEBUG
    if (DEBUG_LEVEL > 0) { Serial.println("Watchdog triggered! Performing recovery..."); }
#endif
    // Restart the Arduino board
    restartBoard();
  }

  //////////////////////////////////////
  // Power Management Integrated Chip //
  //////////////////////////////////////
  /*
  // Deal with battery management
  if (millis() - time_last_battery_interrupt > loopPeriod) {
    // Enable the Charger
    if (!PMIC.enableCharge()) {
#ifdef DEBUG
      Serial.println("Error enabling Charge mode");
#endif
    }
    // canRunOnBattery() returns true if the battery voltage is < the minimum
    // systems voltage
    if (PMIC.canRunOnBattery()) {
      // loop until charge is done
      if (PMIC.chargeStatus() != CHARGE_TERMINATION_DONE) {
        delay(1000);
      } else {
        // Disable the charger
        Serial.println("Disable Charge mode");
        if (!PMIC.disableCharge()) {
          Serial.println("Error disabling Charge mode");
        }
        // if you really want to detach the battery call
        // PMIC.disableBATFET();
        //isbatteryconnected = false;
      }
    }
  }
*/
  ////////////////////
  // Real work here //
  ////////////////////

  // Read pressure sensor value and convert to actual pressure
  incomingPressureSensorValue = analogRead(incomingPressureSensorPin);
  incomingPressure = map(incomingPressureSensorValue,
                         incomingPressureSensorMinReading,
                         incomingPressureSensorMaxReading,
                         incomingPressureSensorMinPressure,
                         incomingPressureSensorMaxPressure);

  // Send SMS and check if it was successful
  if (!sendPressureSMS(incomingPressure)) {
    // Perform a retry here
    if (!sendPressureSMS(incomingPressure)) {
      // Perform recovery here
#ifdef DEBUG
      if (DEBUG_LEVEL > 1) { Serial.println("Failed to send SMS twice in a row! Performing recovery after waiting for something to change."); }
#endif
      // Sleep a short loop period just in case it can be solved before reset and forget
      LowPower.deepSleep(shortLoopPeriod);
      // Try to report the failure and abort restart if it can be sent
      if (!sendStringSMS("Last SMS report could not be sent and this SMS just prevented a board restart")) {
        // Restart the Arduino board
        restartBoard();
#ifdef DEBUG
      } else {
        if (DEBUG_LEVEL > 1) { Serial.println("SMS report failed to be sent twice, but a third SMS after " + String(shortLoopPeriod) + " seconds ago was successfull. Let's continue."); }
#endif
      }
    }
#ifdef DEBUG
    else {
      if (DEBUG_LEVEL > 1) { Serial.println("Sent SMS on the second try."); }
    }
  } else {
    if (DEBUG_LEVEL > 1) { Serial.println("Sent SMS on the first try."); }
#endif
  }

  // Reset the watchdog flag
  resetWatchdog();

  //////////////////////////////////////
  // Power Management Integrated Chip //
  //////////////////////////////////////
  /*
    To-Do:
    - Check if running on battery when we find out how in order to:
      · tell when the board lost its main power source
      · report back the situation at least once
      · minimize consumption radically
    - Set the GSM chip into low power before deep sleeping the rest of the board
      · this probably means we should reconnect at the beginning of the loop.
  */


  // Put the board into sleep mode
  LowPower.deepSleep(loopPeriod);
}

void batteryInterrupt() {
  time_last_battery_interrupt = millis();
}

void resetWatchdog() {
  // Reset the watchdog timer
  watchdogFlag = false;
}

void restartBoard() {
  // Restart the Arduino board
  NVIC_SystemReset();
}

bool sendPressureSMS(float data) {
  String message = "Pressure reading CCdC: " + String(data, 2) + " bar";
  return sendStringSMS(message);
}

bool sendStringSMS(String message) {
  // Check if the length is lower than the maximumLengthSMS const defined
  if (message.length() > maximumLengthSMS) {
#ifdef DEBUG
    if (DEBUG_LEVEL > 0) { Serial.println("SMS not sent because it was over the defined limits: " + message); }
#endif
    return false;
  }

  // Declare and populate the char array that the sendSMS function needs
  char messageArray[maximumLengthSMS];
  message.toCharArray(messageArray, maximumLengthSMS);

  // Actually send the SMS
  if (sms.beginSMS(controlPhoneNumber)) {
    sms.print(messageArray);
    if (sms.endSMS()) {
#ifdef DEBUG
      if (DEBUG_LEVEL > 0) { Serial.println("SMS sent"); }
#endif
      return true;  // SMS sent successfully
    } else {
#ifdef DEBUG
      if (DEBUG_LEVEL > 0) { Serial.println("Error while sending the SMS"); }
#endif
      return false;  // Failed to send SMS
    }
  } else {
#ifdef DEBUG
    if (DEBUG_LEVEL > 0) { Serial.println("Error starting to send the SMS"); }
#endif
    return false;  // Failed to start SMS
  }
}

////////////////////
// GSM chip tools //
////////////////////

String doATcommandChipGSM(const char* s) {
  String doATresponse;
  doATresponse.reserve(15);
  MODEM.send(s);
  MODEM.waitForResponse(500, &doATresponse);
  return doATresponse;
}

void resetChipGSM() {
  pinMode(GSM_RESETN, OUTPUT);
  digitalWrite(GSM_RESETN, HIGH);
  delay(100);
  digitalWrite(GSM_RESETN, LOW);
  return;
}

I am going to try without the connectr carrier and connect a 5vdc power source i have available directly into the VIN pin of the mkr. That would help identify if the weirdness comes from the mkr board or the shield.

Should I open another thread at that forum or keep here and ask a moderator to move this thread back and forth according to the potential point of failure under investigation?

Confirmed. It is the connector carrier. I connected my 5VDC power source to VIN and GND, and the board happily sent every single SMS without a glitch.

Now, what could be interfering? What does the power stage of the connector carrier shield have in common with the MKR board to even notice when a usb wire and adapter are connected to the micro USB port, even with the charger powered off.

Is there a way to contact oficial arduino support? Because this seems like a hardware defect of some kind.

I managed to get my hands on an usb power blocker, thanks for the suggestion @twesthoff, and i could confirm the mkr sketch becomes "unresponsive" while running the gmaaccess.begin() function while powered only through VIN of the connector carrier. No battery connected yet, but the power source provides 25w so ot should be enough without the aid of the battery at peak consumption events.

It seems to work only when the usb wire is powered, or connected to a Samsung charger (powered or not).

I am guessing there is something missing in my configuration of my carrier power buck maybe. Any ideas on how to troubleshoot this, please?

I can power the controllers from usb only temporarily at a single site. But after a while or at any of the other farms involved, i must make it work straight from the 12 VDC input.

@josiin I do not understand how it works if a USB charger is connected, but not powered, but I believe you.

What you describe seems the way it works for me too. It is not broken. It is a "feature" of the connector carrier board. Makes no sense to me, but that is how it works.

If you disconnect USB cable and jumper 5V to Vin on the MKR 1500 connector strip pins, it will run OK. This is what I am doing. Powered only by Vin on connector carrier board. (Mine must have the LiPo battery connected to work properly even if powered by USB)

Power supply on Vin of connector carrier board, with jumper in, and USB power blocker in the USB cable, you will be able to upload sketches and work normally. 5V will be on Grove connectors and they will work too.

Please, notice your picture includes the imei os your gsm module.

I just installed the battery and it works fine. Charging without software configuration, and the sms are sent without usb cable, charger or pc behind.

Charging led is solid orange, battery voltage is 3.42 volts and 5V pin reads 4.8 volts. Almost like it did with usb.

Now I must wait for the battery to fully charge to verify it all works.

Still. I hate when stuff works just because.

Battery reads 3.67v now and the SMS keep coming, so it seems to be working fine. Charging the battery, deep sleeping properly and sending the sms.

Now into the soldering stage. May be try to use the standby mode of the gsm chip or use gprs against Azure iot central mqtt service.

Bitter sweet case closed. :smiley:

Good luck.
The true test is the 3.3V pin on the MKR 1500. The battery will discharge but as long as the 3,3V is still there the module will work. Of course you will need 5V on the Grove connectors for whatever you have connected to those. The schematics show it is OK to have the jumper as long as you don't apply power with the USB. Even then it probably will not hurt anything, just draw extra current maybe.

That means I could connect the 5V pin to A1 at the grove connector as a monitor to detect when there is power from the carrier (main power source) and when we are running on battery (backup power source where sensors may o may not work properly).

If there is power from VIN, 5V pin reads close to 5 volts. If there is no power from VIN, 5V reads just like VCC: 3.3 volts. I am not sure right now how that translates into LOW or HIGH when the levelling is done at the digital inputs, but it may be possible to use D1 at the grove connector instead of A1 for that self monitor of the power source.

There seems to be a few useful functions from the PMIC library, but I am still struggling to understand the interrupt mode of the example. Also, the documentation on the source files is pretty expert level and I cannot decipher what it does other than reading and masking registers.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.