Go Down

Topic: NB1500 Battery  (Read 604 times) previous topic - next topic

ZeroSix

Sep 17, 2020, 06:11 pm Last Edit: Sep 17, 2020, 07:21 pm by ZeroSix
Hi everyone, i'm having some problem with my Arduino MKR NB 1500
Running from usb cable everything works fine.

I have a 3.7 4000mah Battery attached to the jst Port. The only way to work good is to make a double click on reset button, wait 2 secs and 1 click for reset.

I followed the sketch to send to Azure IOT HUB and I Added a function LowPower.DeepSleep(300000) for sleep during 5 minutes. The problem is that take's on reality 10 minutes and in a lot's of cases just doesn't wake up at all.
Besides LowPower.DeepSleep there is anyway to reduce the consumption?

Other problem is the function getTime since the original code returned from  1980-01-01 .
Any ideas?
Thanks

Code: [Select]

/*
  Azure IoT Hub NB

  This sketch securely connects to an Azure IoT Hub using MQTT over NB IoT/LTE Cat M1.
  It uses a private key stored in the ATECC508A and a self signed public
  certificate for SSL/TLS authetication.

  It publishes a message every 5 seconds to "devices/{deviceId}/messages/events/" topic
  and subscribes to messages on the "devices/{deviceId}/messages/devicebound/#"
  topic.

  The circuit:
  - MKR NB 1500 board
  - Antenna
  - SIM card with a data plan
  - LiPo battery

  The following tutorial on Arduino Project Hub can be used
  to setup your Azure account and the MKR board:

  https://create.arduino.cc/projecthub/Arduino_Genuino/securely-connecting-an-arduino-nb-1500-to-azure-iot-hub-af6470

  This example code is in the public domain.
*/

#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>
#include <utility/ECCX08SelfSignedCert.h>
#include <ArduinoMqttClient.h>
#include <MKRNB.h>
#include <DHT.h>;
#include <ArduinoLowPower.h>



#include "arduino_secrets.h"

//Constants
#define DHTPIN 7     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino

/////// Enter your sensitive data in arduino_secrets.h
const char pinnumber[]   = SECRET_PINNUMBER;
const char broker[]      = SECRET_BROKER;
String     deviceId      = SECRET_DEVICE_ID;

NB nbAccess;
GPRS gprs;
float hum;  //Stores humidity value
float temp; //Stores temperature value

NBClient      nbClient;            // Used for the TCP socket connection
BearSSLClient sslClient(nbClient); // Used for SSL/TLS connection, integrates with ECC508
MqttClient    mqttClient(sslClient);

unsigned long lastMillis = 0;

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(500);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  dht.begin();


  //while (!Serial);

  if (!ECCX08.begin()) {
    Serial.println("No ECCX08 present!");
    while (1);
  }

  // reconstruct the self signed cert
  ECCX08SelfSignedCert.beginReconstruction(0, 8);
  ECCX08SelfSignedCert.setCommonName(ECCX08.serialNumber());
  ECCX08SelfSignedCert.endReconstruction();

  // Set a callback to get the current time
  // used to validate the servers certificate
  ArduinoBearSSL.onGetTime(getTime);

  // Set the ECCX08 slot to use for the private key
  // and the accompanying public certificate for it
  sslClient.setEccSlot(0, ECCX08SelfSignedCert.bytes(), ECCX08SelfSignedCert.length());

  // Set the client id used for MQTT as the device id
  mqttClient.setId(deviceId);

  // Set the username to "<broker>/<device id>/api-version=2018-06-30" and empty password
  String username;

  username += broker;
  username += "/";
  username += deviceId;
  username += "/api-version=2018-06-30";

  mqttClient.setUsernamePassword(username, "");

  // Set the message callback, this function is
  // called when the MQTTClient receives a message
  mqttClient.onMessage(onMessageReceived);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  if (nbAccess.status() != NB_READY || gprs.status() != GPRS_READY) {
    connectNB();
  }

  if (!mqttClient.connected()) {
    // MQTT client is disconnected, connect
    connectMQTT();
  }

  // poll for new MQTT messages and send keep alives
  mqttClient.poll();

  // publish a message roughly every 5 seconds.   
  publishMessage();
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED on (HIGH is the voltage level)
  LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, alarmEvent0, CHANGE);
  LowPower.deepSleep(300000);
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
 

  //delay(30000);
 
}

unsigned long getTime() {
  // get the current time from the cellular module
  return 1600277509;

}

void connectNB() {
  Serial.println("Attempting to connect to the cellular network");

  while ((nbAccess.begin(pinnumber) != NB_READY) ||
         (gprs.attachGPRS() != GPRS_READY)) {
    // failed, retry
    Serial.print(".");
    delay(1000);
  }

  Serial.println("You're connected to the cellular network");
  Serial.println();
}

void connectMQTT() {
  Serial.print("Attempting to MQTT broker: ");
  Serial.print(broker);
  Serial.println(" ");

  while (!mqttClient.connect(broker, 8883)) {
    // failed, retry
    Serial.print(".");
    Serial.println(mqttClient.connectError());
    delay(5000);
  }
  Serial.println();

  Serial.println("You're connected to the MQTT broker");
  Serial.println();

  // subscribe to a topic
  mqttClient.subscribe("devices/" + deviceId + "/messages/devicebound/#");
}

void publishMessage() {
  Serial.println("Publishing message");
 
  temp= dht.readTemperature();
  hum = dht.readHumidity();

  int _temp = (int)(temp * 100);
  int _hum = (int)(hum);

  char messageBytes[3];

  messageBytes[0] = (byte)(_temp & 0xFF);
  messageBytes[1] = (byte) ((_temp >> 8) & 0xFF);
  if(_temp < 0){
    messageBytes[1] = messageBytes[1] | 0x80;
  }
 
  messageBytes[2] = (byte)(_hum & 0xFF);

  Serial.println(_temp);
  Serial.println(_hum);
 

  // send message, the Print interface can be used to set the message contents
  mqttClient.beginMessage("devices/" + deviceId + "/messages/events/");
  mqttClient.print(messageBytes);
  mqttClient.endMessage();
}

void onMessageReceived(int messageSize) {
  // we received a message, print out the topic and contents
  Serial.print("Received a message with topic '");
  Serial.print(mqttClient.messageTopic());
  Serial.print("', length ");
  Serial.print(messageSize);
  Serial.println(" bytes:");

  // use the Stream interface to print the contents
  while (mqttClient.available()) {
    Serial.print((char)mqttClient.read());
  }
  Serial.println();

  Serial.println();
}

ZeroSix

After some strugle I found how to deal with time.
Since nbAccess doesnt return nothing different from 1970 I opted to use a UDP request to a NTP server and store it on RTC.
The issue im facing  at the moment seems the UDP request doesnt work with battery(If I force the value i works normally).

On the first time there is a strange behavior byt getTime function:


Code: [Select]

#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>
#include <utility/ECCX08SelfSignedCert.h>
#include <ArduinoMqttClient.h>
#include <MKRNB.h>
#include <DHT.h>;
#include <ArduinoLowPower.h>
#include <RTCZero.h>
#include "arduino_secrets.h"

//Constants
#define DHTPIN 7     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino

/////// Enter your sensitive data in arduino_secrets.h
const char pinnumber[]   = SECRET_PINNUMBER;
const char broker[]      = SECRET_BROKER;
String     deviceId      = SECRET_DEVICE_ID;

unsigned int localPort = 2390;      // local port to listen for UDP packets
IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

NB nbAccess;
GPRS gprs;
NBUDP Udp;
NBClient      nbClient;            // Used for the TCP socket connection
BearSSLClient sslClient(nbClient); // Used for SSL/TLS connection, integrates with ECC508
MqttClient    mqttClient(sslClient);
NBScanner scannerNetworks;
RTCZero rtc;

float hum;  //Stores humidity value
float temp; //Stores temperature value
boolean isRtcSet = false;

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(500);                       // wait for a second
  scannerNetworks.begin();
  dht.begin();
  rtc.begin();

  //while (!Serial);

  if (!ECCX08.begin()) {
    Serial.println("No ECCX08 present!");
    while (1);
  }

  // reconstruct the self signed cert
  ECCX08SelfSignedCert.beginReconstruction(0, 8);
  ECCX08SelfSignedCert.setCommonName(ECCX08.serialNumber());
  ECCX08SelfSignedCert.endReconstruction();

  // Set a callback to get the current time
  // used to validate the servers certificate
  ArduinoBearSSL.onGetTime(getTime);

  // Set the ECCX08 slot to use for the private key
  // and the accompanying public certificate for it
  sslClient.setEccSlot(0, ECCX08SelfSignedCert.bytes(), ECCX08SelfSignedCert.length());

  // Set the client id used for MQTT as the device id
  mqttClient.setId(deviceId);

  // Set the username to "<broker>/<device id>/api-version=2018-06-30" and empty password
  String username;

  username += broker;
  username += "/";
  username += deviceId;
  username += "/api-version=2018-06-30";

  mqttClient.setUsernamePassword(username, "");

  // Set the message callback, this function is
  // called when the MQTTClient receives a message
  //mqttClient.onMessage(onMessageReceived);
}

void loop() {
  if (nbAccess.status() != NB_READY || gprs.status() != GPRS_READY) {
    connectNB();
  }

  bool mqttConnected = mqttClient.connected();

  if (!mqttConnected) {
    connectMQTT();
  } else {
    // poll for new MQTT messages and send keep alives
    //mqttClient.poll();

    publishMessage();
    delay(120000);
  }
}

unsigned long getTime() {
  if (!isRtcSet) {
    setUdp();
    boolean hasTime = false;
    while (!hasTime) {
      unsigned long currentTime = getNTPTime();
      if (currentTime > 0) {
        hasTime = true;
        Udp.stop();
        rtc.setEpoch(currentTime);
        isRtcSet = true;
        Serial.println("GetTime with Success!");
        Serial.println(currentTime);
        digitalWrite(LED_BUILTIN, LOW);
        return currentTime;
      }
      else {
        Serial.println("GetTime Failed!");
      }
    }
  }
  else {
    Serial.println("GetTime From Epoch!!!!!");
    return rtc.getEpoch();
  }

  //return 1600608021;
}

void connectNB() {
  Serial.println("Attempting to connect to the cellular network");

  while ((nbAccess.begin(pinnumber) != NB_READY) ||
         (gprs.attachGPRS() != GPRS_READY)) {
    // failed, retry
    Serial.print(".");
    delay(1000);
  }

  Serial.println("You're connected to the cellular network");
  Serial.println();
}

void connectMQTT() {
  Serial.print("Attempting to MQTT broker: ");
  Serial.print(broker);
  Serial.println(" ");

  if (!mqttClient.connect(broker, 8883)) {
    // failed, retry
    Serial.println(mqttClient.connectError());
    delay(5000);
  }
  Serial.println("You're connected to the MQTT broker");
  // subscribe to a topic
  mqttClient.subscribe("devices/" + deviceId + "/messages/devicebound/#");
}

void publishMessage() {
  Serial.println("Publishing message");
  temp = dht.readTemperature();
  hum = dht.readHumidity();
  float batVoltage = analogRead(ADC_BATTERY) * 3.3 / 1023.0 * 1.275;
  int _batVoltage = batVoltage* 100;
  int _temp = (int)(temp * 100);
  int _hum = (int)(hum);
  String _signalStrengh = scannerNetworks.getSignalStrength();
  unsigned long timestamp = rtc.getEpoch();

  Serial.println(_temp);
  Serial.println(_hum);
  Serial.println(_batVoltage, BIN);
  Serial.println(_signalStrengh);
  Serial.println(rtc.getEpoch());
  char messageBytes[10];

  messageBytes[0] = (byte)(_temp & 0xFF);
  messageBytes[1] = (byte) ((_temp >> 8) & 0xFF);
  if (_temp < 0) {
    messageBytes[1] = messageBytes[1] | 0x80;
  }

  messageBytes[2] = (byte)(_hum & 0xFF); 
  messageBytes[3] = (byte)(_batVoltage & 0xFF);
  messageBytes[4] = (byte)((_batVoltage >> 8) & 0xFF);
  messageBytes[5] = (byte)(_signalStrengh.toInt()); 
  messageBytes[6] = (byte)(timestamp & 0xFF); 
  messageBytes[7] = (byte)((timestamp >> 8) & 0xFF); 
  messageBytes[8] = (byte)((timestamp >> 16) & 0xFF);   
  messageBytes[9] = (byte)((timestamp >> 24) & 0xFF); 

  // send message, the Print interface can be used to set the message contents
  mqttClient.beginMessage("devices/" + deviceId + "/messages/events/");
  mqttClient.print(messageBytes);
  mqttClient.endMessage();
}

unsigned long getNTPTime() {
  sendNTPpacket(timeServer);
  delay(1000);
  if ( Udp.parsePacket() ) {
    Serial.println("packet received");
    Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    Serial.print("Unix time = ");
    const unsigned long seventyYears = 2208988800UL;
    unsigned long epoch = secsSince1900 - seventyYears;
    // print Unix time:
    Serial.println(epoch);
    return epoch;
  } else {
    delay(10000);
    return 0;
  }
}

unsigned long sendNTPpacket(IPAddress& address) {
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011;
  packetBuffer[1] = 0;
  packetBuffer[2] = 6;
  packetBuffer[3] = 0xEC;
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  Udp.beginPacket(address, 123);
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

void setUdp() {
  Serial.println("Starting Arduino GPRS NTP client.");
  // connection state
  boolean connected = false;

  while (!connected) {
    if ((nbAccess.begin(pinnumber) == NB_READY) &&
        (gprs.attachGPRS() == GPRS_READY)) {
      connected = true;
    } else {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("\nStarting UDP Server...");
  Udp.begin(localPort);
}




ZeroSix

After some debug with internal led.
Seems when using battery after added the UDP, the function connectNB doesnt work.
Anyone else had this problem? im using an 3.7 attached to jst port (4000 mah)

scouter9000

Hi ZeroSix,

I have have had some similar challenges in my system operating on AWS IOT MQTT. I had thought that it was due to the modem not enjoying being put to sleep then woken up again and asked to do thing straight away. My system has two power states - one that sends every 1 minute simply using delay to wait between sends, then a low power mode running off of the battery, where the modem is shut down and the processor put to sleep, that sends every 20 minutes. My low power mode lasts 30 days on a 3400mAh 18650.

If you would like to increase your battery life, call nbAccess.shutdown() before sleep, and nbAccess.begin() after, here is the relevant portion in my code:

Code: [Select]
   nbAccess.shutdown();
    Serial.println("Modem Shutdown");

    for (int i = 0; i < 12; i++) {
    Watchdog.clear(); //reset watchdog before it loops
    LowPower.deepSleep(30000); // wait 5 minutes
    }

    Serial.println("Awake!");
    
    //boot and setup the modem
    nbAccess.begin();



In the low power mode, after waking up from sleep and turning the modem back on I more often than not get a successful cellular connection, and then the same failure to retrieve time from the NTP server over UDP that you describe above. 

I originally addressed this by just forcing a watchdog reset upon waking at the end of the 20 minutes, thereby restarting the program from scratch. This proved very reliable in connecting successfully every time. This approach may be something that works for you.

However, I require IOs to be persistently held at certain states, which is lost upon the reset, so I am trying to solve this problem directly.

My initial thoughts were that even though the modem is able to report a successful connection to the network, there is still some background tasks that prevent it from functioning properly. However in your code you never put the modem to sleep so I'm beginning to doubt that this is the case.


Just today, I've added Udp.stop() to the end of my epoch retrieval, that releases all resources. Then after my system awakes I begin the Udp.begin(localPort) again afresh. This tentatively appears to have removed the time retrieval failures and subsequent MQTT failures, but more testing is needed.  Here are my Time functions:



Code: [Select]
unsigned long refreshTime() {
  sendNTPpacket(timeServer); // send an NTP packet to a time server
  // wait to see if a reply is available
  delay(3000);
  if ( Udp.parsePacket() ) {
    // We've received a packet, read the data from it
    Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    // now convert NTP time into everyday time:
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    Serial.println("Time successfully retrieved!");
    Serial.println("Time successfully retrieved!");
    Serial.println("Time successfully retrieved!");
    Serial.println(epoch);
    Udp.stop();
    Serial.println("UDP Closed");
    return epoch;
  } else {
    unsigned long epoch = getTime();
    Serial.println("Time Failure!");
    Serial.println(epoch);
    Udp.stop();
    Serial.println("UDP Closed");
    return epoch;
  }
}

unsigned long sendNTPpacket(IPAddress& address) {
  //Serial.println("1");
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  //Serial.println("2");
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  //Serial.println("3");

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  //Serial.println("4");
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  //Serial.println("5");
  Udp.endPacket();
  //Serial.println("6");
}



Hope that's all helpful to you and there's a couple of solutions for you to try.

Best,
Tom

ZeroSix

Thanks for the idea. Watchdog seems to be good idea.
I confess this board is a pure pain.
I dont know why the sketch doesnt work when only powered to a battery :S

ZeroSix

I used another board with the version  L0.0.00.00.05.06,A.02.00 [Feb 03 2018 13:00:41] and seems it connects fine only using battery. the 02.16 cannot connect to nbiot only using battery. My knowledge is a bit low in this area.

ZeroSix

Hi ZeroSix,

I have have had some similar challenges in my system operating on AWS IOT MQTT. I had thought that it was due to the modem not enjoying being put to sleep then woken up again and asked to do thing straight away. My system has two power states - one that sends every 1 minute simply using delay to wait between sends, then a low power mode running off of the battery, where the modem is shut down and the processor put to sleep, that sends every 20 minutes. My low power mode lasts 30 days on a 3400mAh 18650.

If you would like to increase your battery life, call nbAccess.shutdown() before sleep, and nbAccess.begin() after, here is the relevant portion in my code:

Code: [Select]
   nbAccess.shutdown();
    Serial.println("Modem Shutdown");

    for (int i = 0; i < 12; i++) {
    Watchdog.clear(); //reset watchdog before it loops
    LowPower.deepSleep(30000); // wait 5 minutes
    }

    Serial.println("Awake!");
    
    //boot and setup the modem
    nbAccess.begin();



In the low power mode, after waking up from sleep and turning the modem back on I more often than not get a successful cellular connection, and then the same failure to retrieve time from the NTP server over UDP that you describe above.

I originally addressed this by just forcing a watchdog reset upon waking at the end of the 20 minutes, thereby restarting the program from scratch. This proved very reliable in connecting successfully every time. This approach may be something that works for you.

However, I require IOs to be persistently held at certain states, which is lost upon the reset, so I am trying to solve this problem directly.

My initial thoughts were that even though the modem is able to report a successful connection to the network, there is still some background tasks that prevent it from functioning properly. However in your code you never put the modem to sleep so I'm beginning to doubt that this is the case.


Just today, I've added Udp.stop() to the end of my epoch retrieval, that releases all resources. Then after my system awakes I begin the Udp.begin(localPort) again afresh. This tentatively appears to have removed the time retrieval failures and subsequent MQTT failures, but more testing is needed.  Here are my Time functions:



Code: [Select]
unsigned long refreshTime() {
  sendNTPpacket(timeServer); // send an NTP packet to a time server
  // wait to see if a reply is available
  delay(3000);
  if ( Udp.parsePacket() ) {
    // We've received a packet, read the data from it
    Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    // now convert NTP time into everyday time:
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    Serial.println("Time successfully retrieved!");
    Serial.println("Time successfully retrieved!");
    Serial.println("Time successfully retrieved!");
    Serial.println(epoch);
    Udp.stop();
    Serial.println("UDP Closed");
    return epoch;
  } else {
    unsigned long epoch = getTime();
    Serial.println("Time Failure!");
    Serial.println(epoch);
    Udp.stop();
    Serial.println("UDP Closed");
    return epoch;
  }
}

unsigned long sendNTPpacket(IPAddress& address) {
  //Serial.println("1");
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  //Serial.println("2");
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  //Serial.println("3");

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  //Serial.println("4");
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  //Serial.println("5");
  Udp.endPacket();
  //Serial.println("6");
}



Hope that's all helpful to you and there's a couple of solutions for you to try.

Best,
Tom
Im quite new in using the watchdog.
What configuration did you used?
From what I understand the max configurable is 8 secs. And after the counter reach the timer without a watch dog reset, the divice will reset.
I applied 30secs deepsleeps and the device works fine.
Thanks for the tip :)

ZeroSix

#7
Nov 05, 2020, 12:34 am Last Edit: Nov 05, 2020, 12:37 am by ZeroSix
Another day another pain.
I picked a new clean board
Seems the code make a publish but doesnt reach the broker.
I think the modem consumes too much(I have also one DHT22 connected) and I usually have better results without it.
Seems the problems occur more when the signal strength is low.

Anyone can help me interpret this AT commands?


ZeroSix

I switched the antenna and i'm getting better results.^
Im struggling with the LowPower.DeepSleep.
I don't know if is related, but after making a publish how can I check if is already sen't? I think going to deepsleep after the publish is havings problems

lavignema

The reason the power circuit acts differently is because they omitted Diode D3 from the assembly. The part number is PMEG6020 and it is missing from the pads right next to the J4 connector. If you have a solder rework station you can install it onto the pads and restore the power as it was for the MKR GSM1400. I needed the device to operate a GPS shield while on battery. This is what I did to restore it to full function. The only real alternative is to power it through the USB port.

tangram67

#10
Jan 14, 2021, 10:01 am Last Edit: Jan 14, 2021, 10:24 am by tangram67
@lavignema

I found out that the system voltage drops from 3.3V to 2.5V as soon as the USB or the external power Supply (VIN at 5V) is disconnected. If you take a look in the manual for the u-blox SARA modem chip, the voltage is too low for the modem to work. This might be (is) the reason why the transmitter is not working properly.

As far as understand from the scematics the missing diode D3 is connecting the PMID output back to VBUS input. So the whole system is running on 5 Volts again.

So can you please confirm that the 2 marked pads in attachment are the pads to place the diode on?





zbelding

@lavignema

I found out that the system voltage drops from 3.3V to 2.5V
In my experience, this usually means that the Power Management IC is damaged. Does your board make an audible high pitch switching noise while running?
The PMIC on this board is easily damaged. I have damaged 2. I believe that both of mine were damaged by accidentally shorting the battery connector pins.
In my experience, I had the 2.5V you speak of only when powered by USB. The mosfet that switches between Vin and USB is not fully switching when the PMIC is damaged. If you want to power via USB and have a damaged PMIC, you can make it work by pulling Vin to ground with a resistor. The arduino board already does this with a 1.2 Mohm resistor, but it is not enough when the PMIC is damaged.

tangram67

#12
Jan 15, 2021, 12:25 pm Last Edit: Jan 15, 2021, 01:10 pm by tangram67
@zbelding

I think you must be right!
I also found out that pulling VIN to GND is needed for normal function. But that does not restore the board to work on battery.

I will replace the PMIC chip an come back with further information....

tangram67

#13
Jan 21, 2021, 05:49 pm Last Edit: Jan 21, 2021, 05:53 pm by tangram67
I got the BQ24195L chip replaced and the MKR board is working as expected. The board is running on battery and also charging the battery again.

zbelding

I got the BQ24195L chip replaced and the MKR board is working as expected. The board is running on battery and also charging the battery again.
Nice! Arduino should really consider an overcurrent device between BQ24195L and the battery plug.

Go Up