khoih-prog / NB_Generic

Enables NB-IoT/LTE-M/GRPS network connection using the NB-IoT/LTE-M/GRPS modules. Use this library to send and receive SMS using Generic NB-IoT/LTE-M/GRPS modules, such as u-blox SARA-R410M module.This library also allows you to connect to internet through the GPRS networks. You can also use Web Clients to connect to Blynk, MQTT.
GNU General Public License v3.0
23 stars 3 forks source link

Sara shield connected to MKRNB1500 #1

Closed elevraadforman closed 3 years ago

elevraadforman commented 3 years ago

The modem on my ARDUINO_SAMD_MKRNB1500 is broken, and wanted to test the library using Microe LTE IoT Click (SARA-R410M-02B modem) connected to the MKRNB board. To get this work I would use hardware Serial1 (pin 13&14) and NB_RESETN&NB_PWR (pin 3&2 in my case). However, in the defines.h file SerialNB is defined to SerialSARA for the MKRNB1500, while RST&PWR are defined to initial pins. Is it possible to use my setup with this library, and if so any tips to how change the defines,h file?

khoih-prog commented 3 years ago

Hi @elevraadforman

Thanks for your interests in the library. I'll have a look at the issue, do some research and will reply soon.

If possible, can you post a drawing of your wiring connection. You can also try the library, with debug level 5 to see if the new modem is responding, and post the result to help locate the issue.

khoih-prog commented 3 years ago

Hi @elevraadforman

You can try to change defines.h as follows and test. Please inform if it's working or not.

...

#if defined(ARDUINO_SAMD_MKRNB1500)

  #define USING_CUSTOMIZED_MKRNB1500      true

  #if USING_CUSTOMIZED_MKRNB1500

    #define SerialNB      Serial1
    #define NB_RESETN     (3u)
    #define NB_PWR        (2u)

  #else

    #define SerialNB      SerialSARA
    #define NB_RESETN     SARA_RESETN
    #define NB_PWR        SARA_PWR_ON

  #endif
#else
  // Override the default (and certainly not good) pins and port
  // Only for boards other than ARDUINO_SAMD_MKRNB1500
  #define NB_RESETN  (10u)
  #define NB_PWR     (11u)

  #if ESP8266
    // Using Software Serial for ESP8266, as Serial1 is TX only
    #define NB_USING_SOFTWARE_SERIAL     true
  #else
    // Optional Software Serial here for other boards, but not advised if HW Serial available
    #define NB_USING_SOFTWARE_SERIAL     false
  #endif

  #if NB_USING_SOFTWARE_SERIAL
    #warning Using default SerialNB = SoftwareSerial

    #define D8 (15)
    #define D7 (13)

    #include <SoftwareSerial.h>

    SoftwareSerial swSerial(D7, D8);    // (D7, D8, false, 256); // (RX, TX, false, 256);

    #define SerialNB   swSerial
  #else
    #warning Using default SerialNB = HardwareSerial Serial1
    #define SerialNB   Serial1
  #endif    // NB_USING_SOFTWARE_SERIAL

  #warning You must connect the Modem correctly and modify the pins / Serial port here

#endif

...

NB: Pins 2 and 3 have been assigned for I2S as PIN_I2S_SCK and PIN_I2S_FS

#define PIN_I2S_SCK         (2u)
#define PIN_I2S_FS          (3u)

Just be aware if there is any conflict.

elevraadforman commented 3 years ago

hello @khoih-prog , thanks for answer and suggestions! I have tried couple of things, but unfortunately without success yet. First, here is the wiring: wiring

Also, it is necessary to mention that the mkrnb1500 board and the IoT Click module work as the Serial_Passtrough example provided by https://github.com/sparkfun/SparkFun_LTE_Shield_Arduino_Library works with the given wiring.

Have tried your suggestion for defines.h in the NB_Generic Serial_Passtrough example, resulting in no contact to modem, but also it seem that the modem turn on and then register to network (both events indicated by led's, see https://www.mikroe.com/lte-iot-click for reference) before both turn off. Then, this behaviour is looping. When running the NB_Generic TestModem example this is the output: Starting NBSendSMS on SAMD MKRNB1500 NB_Generic v1.1.0 Starting modem test...[NB] begin: UART baud = 115200 [NB] begin: Check autosense [NB] begin: autosense error ERROR, no modem answer. Checking IMEI...Error: Could not get IMEI

Have also changed the Variant.h and .cpp file to define Serial1 as SerialSARA , adding the RTS(16u) and CTS(17u) as defined for sercom5. This because both pins are defined for SerialSARA initially, enabling hardware flow control. Wiring to the modem board for the two pins was added. Both the original NB_Generic Serial_Passtrough and MKRNB Serial_Passtrough examples compiled. They did not work, and showed the same behaviaour as described above, modem turning on, registering to network before turning off. Any ideas why and where to go further to get this work? best regards

khoih-prog commented 3 years ago

It's good that you've done a lot of research on the issue.

Did you change anything in the SparkFun_LTE_Shield_Arduino_Library's Serial_Passthrough code? Such as

// Create a SoftwareSerial object to pass to the LTE_Shield library
SoftwareSerial lteSerial(8, 9);

...
if ( lte.begin(lteSerial, 9600) ) {

Orig.code

// Create a SoftwareSerial object to pass to the LTE_Shield library
SoftwareSerial lteSerial(8, 9);
// Create a LTE_Shield object to use throughout the sketch
LTE_Shield lte;

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

  if ( lte.begin(lteSerial, 9600) ) {
    Serial.println(F("LTE Shield connected!"));
  }
  Serial.println(F("Ready to passthrough!\r\n"));
}

If orignal MKRNB Serial_Passthrough example still has issue to communicate with the modem, I guess the HardwareSerial Serial1 we're trying to use is not fully working.

I suggest you can try these following tests (after restoring the orig. variant.h/cpp)

  1. Using SerialSoftware by modifying and adding something similar to
#if NB_USING_SOFTWARE_SERIAL
    #warning Using default SerialNB = SoftwareSerial

    #define D8 (15)
    #define D7 (13)

    #include <SoftwareSerial.h>

    SoftwareSerial swSerial(D7, D8);    // (D7, D8, false, 256); // (RX, TX, false, 256);

    #define SerialNB   swSerial
  #else
    #warning Using default SerialNB = HardwareSerial Serial1
    #define SerialNB   Serial1
  #endif    // NB_USING_SOFTWARE_SERIAL
  1. Lower Serial speed to 9600

  2. Did you receive the following or any other informative warnings when compile

#warning Using NB_RESETN and NB_PWR pins from sketch

As I don't have the MKRNB 1500 as well as the modem you have, it's almost impossible to understand what this interesting problem is.

Good Luck,

tcpipchip commented 3 years ago

Hi how are powering the Module ? Is your power supply enough ? 2A ?

elevraadforman commented 3 years ago

hi @khoih-prog, yes, I had to change the Serial_Passthrough example to remove SoftwareSerial and change to Serial1:

//Create a SoftwareSerial object to pass to the LTE_Shield library
//SoftwareSerial lteSerial(8, 9);

...
if ( lte.begin(Serial1, 9600) ) {

Then it was necessary to change the pin for PWR and RESETN in the library. As this code worked it was clear that baud rate was ok. Now I found that the issue is with hardware and specifically the way the PWR and RESETN are coupled between SARA modem and MKRNB board, internally for the MKRNB transistors are used while for the LTE IoT Click shield couples them directly and a button is applied for PWR, see difference here: MKR_vs_microe

Therefore, using your suggestion in defines.h file and changing the NB_Generic SerialNBAPassthrough example code regarding pinMode and digitalWrite works fine. See changes below:

// baud rate used for both Serial ports
unsigned long baud = 9600; //115200;

#include "defines.h"

void setup() 
{
  // NEVER EVER use RESET_N
//  pinMode(NB_RESETN, OUTPUT);
    pinMode(NB_RESETN, INPUT);
//  digitalWrite(NB_RESETN, LOW);

  // Send Poweron pulse
  pinMode(NB_PWR, OUTPUT);
  digitalWrite(NB_PWR, LOW);
  delay(150);
//  digitalWrite(NB_PWR, LOW);
  pinMode(NB_PWR, INPUT);

  Serial.begin(baud);
  SerialNB.begin(baud);
}

void loop() 
{
  if (Serial.available()) 
  {
    SerialNB.write(Serial.read());
  }

  if (SerialNB.available()) 
  {
    Serial.write(SerialNB.read());
  }
}

However, the code works only with baud rate of 9600. It turned out to be relevant issue for this library in the end. I assume this solution has to be implemented for the cases where a SARA shield without transistors is used. Do you also see it necessary?

elevraadforman commented 3 years ago

hi @tcpipchip , actually I partly do this to test the reliability difference in sending data between MKRNB1500 and the LTE IoT Click shield. The difference is in power supply (?). In final setup the LTE IoT shield will have external 5v supply. The LTE IoT shield uses MCP1826 LDO regulator rated to 1A.

tcpipchip commented 3 years ago

Ok, 1A is enough! Maximum R410M, N410 0.5 A

tcpipchip commented 3 years ago

The default baud rate is 115’200 b/s • The default frame format is 8N1 (8 data bits, no parity, 1 stop bit) ☞ Hardware flow control is not supported by the “00B”, “01B” and SARA-R410M-02B product versions, but the RTS input line needs to be set low (= ON state) to communicate over the UART interface on the “00B” and “01B” product versions.

The UART serial interface can be conveniently configured through AT commands

Source: https://www.u-blox.com/sites/default/files/SARA-R4_DataSheet_UBX-16024152.pdf

khoih-prog commented 3 years ago

Hi @elevraadforman

It's great you made a good progress.

From the schematics, it turns out that the real issue is that the polarity of the signal NB_RESETN and NB_PWR has been reversed by the MOSFET (that's why _N at the end of the name).

  1. With original MKRNB1500,
    • NB_RESETN == LOW => normal working. NB_RESETN == HIGH => reset (pin RESETN)
// datasheet warns not to use _resetPin, this may lead to an unrecoverable state
digitalWrite(_resetPin, LOW);
      // power on module
      if (isPowerOn() == NB_MODEM_START_ERROR)
      {
        NB_LOGDEBUG(F("begin: Reset"));
        digitalWrite(_powerOnPin, HIGH);

        delay(150); // Datasheet says power-on pulse should be >=150ms, <=3200ms

        digitalWrite(_powerOnPin, LOW);

        setVIntPin(SARA_VINT_ON);
        NB_LOGDEBUG(F("begin: Reset done"));
      }
  1. With modified MKRNB1500 (no MOSFET)
    • NB_RESETN == HIGH => normal working. NB_RESETN == LOW => reset (pin RESETN)

Therefore, pls try

  1. the new code (to reversed the polarity) of as follows.
// baud rate used for both Serial ports
unsigned long baud = 9600; //115200;

#include "defines.h"

void setup() 
{
  // NEVER EVER use RESET_N
  pinMode(NB_RESETN, OUTPUT);
  digitalWrite(NB_RESETN, HIGH);

  // Send Poweron pulse
  pinMode(NB_PWR, OUTPUT);
  digitalWrite(NB_PWR, LOW);
  delay(150);
  digitalWrite(NB_PWR, HIGH);

  Serial.begin(baud);
  SerialNB.begin(baud);
}

void loop() 
{
  if (Serial.available()) 
  {
    SerialNB.write(Serial.read());
  }

  if (SerialNB.available()) 
  {
    Serial.write(SerialNB.read());
  }
}

However, the code works only with baud rate of 9600.

The default baud rate is 115’200 b/s

It's possible you or the code has changed the baudRate to 9600 and the settings is saved. Just issue AT command to set baudRate back to 115Kb and save the settings. You can use SerialPassthru to do this.

  1. Because this is a special case yet it will be much more popular for people using boards other than MKRNB 1500, we certainly will modify the lib to take care of the issue (configurable). But we'll wait until the dust is settled after you're successful with your tests.

Cheers,

elevraadforman commented 3 years ago

hi @khoih-prog , yes, the code in 1. above works fine. you were right in 2., as you see in the AT commands:

AT+IPR? 
+IPR:9600 

OK
AT+IPR=115200

OK
AT+IPR?
+IPR:115200 

OK

and when changed to the original baud rate worked fine. Thanks for help! I will have a look and maybe test/change the polarity in the code before you have time to implement it. The changes should be done only in Modem_SaraR4_Generic.h or are there other places? regards

khoih-prog commented 3 years ago

The mods will be possibly done in

#if RESET_PIN_REVERSED_POLARITY
  // For orig. MKRNB 1500
  #define NB_MODEM_RESET_ON        HIGH
  #define NB_MODEM_RESET_OFF       LOW
#else
  #define NB_MODEM_RESET_ON        LOW
  #define NB_MODEM_RESET_OFF       HIGH
#endif

#if POWER_PIN_REVERSED_POLARITY
  // For orig. MKRNB 1500
  #define NB_MODEM_POWER_ON        LOW
  #define NB_MODEM_POWER_OFF       HIGH
#else
  #define NB_MODEM_POWER_ON        HIGH
  #define NB_MODEM_POWER_OFF       LOW
#endif
int begin(unsigned long baud, bool restart = false)
    {
      // datasheet warns not to use _resetPin, this may lead to an unrecoverable state
      digitalWrite(_resetPin, NB_MODEM_RESET_OFF);

      if (restart)
      {
        shutdown();
        end();
      }

      bool newBaud = false;

      if (_baud != baud)
      {
        _baud = ( baud > 115200 ? 115200 : baud );
        newBaud = true;
      }

      NB_LOGDEBUG1(F("begin: UART baud = "), _baud);

      _uart->begin(_baud > 115200 ? 115200 : _baud);

#if UBLOX_USING_POWER_ON_PIN
      // power on module
      if (isPowerOn() == NB_MODEM_START_ERROR)
      {
        NB_LOGDEBUG(F("begin: Reset"));
        digitalWrite(_powerOnPin, NB_MODEM_POWER_OFF);

        delay(150); // Datasheet says power-on pulse should be >=150ms, <=3200ms

        digitalWrite(_powerOnPin, NB_MODEM_POWER_ON);

        setVIntPin(SARA_VINT_ON);
        NB_LOGDEBUG(F("begin: Reset done"));
      }
      else
      {
        if (!autosense())
        {
          NB_LOGDEBUG(F("begin: nonrestart autosense error"));
          return NB_MODEM_START_ERROR;
        }
      }
#endif

      NB_LOGDEBUG(F("begin: Check autosense"));

      if (!autosense())
      {
        NB_LOGDEBUG(F("begin: autosense error"));
        return NB_MODEM_START_ERROR;
      }

      NB_LOGDEBUG(F("begin: Check baud"));

      // KH, must always set baud here
      if ( restart || newBaud )
      {
        NB_LOGDEBUG1(F("begin: Set baud = "), _baud);

        sendf("AT+IPR=%ld", _baud);

        if (waitForResponse() != NB_RESPONSE_OK)
        {
          NB_LOGDEBUG(F("begin: Set baud error"));
          return NB_MODEM_START_ERROR;
        }

        _uart->end();
        delay(100);
        _uart->begin(_baud);

        if (!autosense())
        {
          NB_LOGDEBUG(F("begin: Set baud autosense error"));
          return NB_MODEM_START_ERROR;
        }
      }

      return NB_MODEM_START_OK;
    }
void setup() 
{
  pinMode(NB_RESETN, OUTPUT);
  digitalWrite(NB_RESETN, NB_MODEM_RESET_OFF);

  // Send Poweron pulse
  pinMode(NB_PWR, OUTPUT);
  digitalWrite(NB_PWR, NB_MODEM_POWER_OFF);
  delay(150);
  digitalWrite(NB_PWR, NB_MODEM_POWER_ON);

  Serial.begin(baud);
  SerialNB.begin(baud);
}

  1. defines.h in every sketch, so that user can pick either
// Default is true, for MKRNB 1500
#define RESET_PIN_REVERSED_POLARITY               false
#define POWER_PIN_REVERSED_POLARITY               false

or

// Default is true, for MKRNB 1500
#define RESET_PIN_REVERSED_POLARITY               true
#define POWER_PIN_REVERSED_POLARITY               true

Would you pls test using other examples to see if there is any other issue so that we know the problem has been solved.

tcpipchip commented 3 years ago

@elevraadforman Are you using 3G or NB IoT or CAT M ?

elevraadforman commented 3 years ago

@tcpipchip Using RAT = 7,8. That is LTE CAT M1 and NB1

elevraadforman commented 3 years ago

@khoih-prog Yes, will do that

elevraadforman commented 3 years ago

@khoih-prog before I start testing; would it also be necessary to change mkrnb1500/variant.cpp due to this issue#550 related to use of the MKRNB library? Change would mean go back to the version before issue#550 was fixed because of the poloarity.

khoih-prog commented 3 years ago

It's not necessary, but up to you, because

  1. We already have option to disable the RESETN pin, and default is false meaning not using RESETN
//////////////////////////////////////////////

// Optional usage of NB_RESETN and NB_DTR. Need to be here only when true. Default is false

//#define UBLOX_USING_RESET_PIN             true
//#define UBLOX_USING_POWER_ON_PIN          true

//////////////////////////////////////////////
  1. You have external modem and can connect the RESETN to HIGH.

Just be sure when you compile, you see the

#warning No UBLOX_USING_RESET_PIN
#warning No UBLOX_USING_POWER_ON_PIN

In Modem_SaraR4_Generic.h#L60-L72

#if !defined(UBLOX_USING_RESET_PIN)
  #define UBLOX_USING_RESET_PIN    false
  #warning No UBLOX_USING_RESET_PIN
#elif UBLOX_USING_RESET_PIN
  #warning UBLOX_USING_RESET_PIN
#endif

#if !defined(UBLOX_USING_POWER_ON_PIN)
  #define UBLOX_USING_POWER_ON_PIN    false
  #warning No UBLOX_USING_POWER_ON_PIN
#elif UBLOX_USING_POWER_ON_PIN
  #warning UBLOX_USING_POWER_ON_PIN
#endif
khoih-prog commented 3 years ago

@tcpipchip

Can you check with u-blox as well as documents to see if we can do something better?

image

khoih-prog commented 3 years ago

Hi @elevraadforman

I'm hoping everything is OK with you so far. I'm closing this issue now.