Open splitout opened 5 years ago
Hi @splitout,
Can you please enable debug output in the MKRNB lib and copy paste the output of the serial monitor?
To do so you'll need to change the NB nbAccess;
line in the sketch to NB nbAccess(true);
.
What SIM card and provider are you using?
Hi @sandeepmistry,
Iam using the SIM card provider 1NCE. the debug mode was enabled. Here the output:
Thank you for your help.
After the connecton to cellular network I tried to get the time with: Serial.println(getTime()); AT+CCLK? +CCLK: "80/01/06,00:00:20" Then again after trying connecting to MQTT:
Do you have any idea why it might be?
Attempting to connect to the cellular network
any reasons?
I used X.508 but on Azure still using X.509?!?!
Thanks
Can you try the below code and let us know the update of the serial monitor with enable debugging by NB nbAccess(true);
Please make sure that you are löog in with your credentials on Azure account with Nb 1500 device.
/*
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 <NBUdp.h>
#include "arduino_secrets.h"
/////// 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;
NBUDP Udp;
NBClient nbClient; // Used for the TCP socket connection
BearSSLClient sslClient(nbClient); // Used for SSL/TLS connection, integrates with ECC508
MqttClient mqttClient(sslClient);
const char* timeServer = "time.nist.gov";
const int NTP_PACKET_SIZE = 48;
unsigned long lastMillis = 0;
void setup() {
Serial.begin(9600);
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();
}
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.
if (millis() - lastMillis > 5000) {
lastMillis = millis();
publishMessage();
}
}
void sendNTPpacket(uint8_t* packetBuffer) {
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(timeServer, 123);
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
unsigned long getTime() {
unsigned int localPort = 8888;
uint8_t packetBuffer[NTP_PACKET_SIZE];
Udp.begin(localPort);
sendNTPpacket(packetBuffer);
long start = millis();
while (!Udp.parsePacket() && (millis() - start < 10000)) {}
if (millis() - start >= 1000) {
//timeout reached
Udp.stop();
return 0;
}
Udp.read(packetBuffer, NTP_PACKET_SIZE);
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = highWord << 16 | lowWord;
const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 - seventyYears;
Udp.stop();
return epoch;
}
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");
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage("devices/" + deviceId + "/messages/events/");
mqttClient.print("hello ");
mqttClient.print(millis());
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();
}
Hi @PRAhit,
actually I tested your example. Now I got the Error-Code (-2) shows txt-file and example.ino
The ECCX08 is active. Please enter the issue year of the certificate? (2000 - 2031) [2019]: 2019 Please enter the issue month of the certificate? (1 - 12) [1]: 6 Please enter the issue day of the certificate? (1 - 31) [1]: 14 Please enter the issue hour of the certificate? (0 - 23) [0]: 12 Please enter how many years the certificate is valid for? (1 - 31) [31]: 31 What slot would you like to use for the private key? (0 - 4) [0]: 0 What slot would you like to use for storage? (8 - 15) [8]: 8 Would you like to generate a new private key? (Y/n) [Y]: Y
The SHA1 key is deposited to azure device on primary and secondary thumbprint.
After the first try to connect with the mqtt broker, the loop oft he mqtt connect freezes again.
Next test with a new ECCX08 certificate :
Please enter the issue year of the certificate? (2000 - 2031) [2019]: 2019 Please enter the issue month of the certificate? (1 - 12) [1]: 07 Please enter the issue day of the certificate? (1 - 31) [1]: 22 Please enter the issue hour of the certificate? (0 - 23) [0]: 15 Please enter how many years the certificate is valid for? (1 - 31) [31]: 31 What slot would you like to use for the private key? (0 - 4) [0]: 4 What slot would you like to use for storage? (8 - 15) [8]: 15 Would you like to generate a new private key? (Y/n) [Y]: Y
with: ECCX08SelfSignedCert.beginReconstruction(4, 15); and sslClient.setEccSlot(4, ECCX08SelfSignedCert.bytes(), ECCX08SelfSignedCert.length()); or sslClient.setEccSlot(0, ECCX08SelfSignedCert.bytes(), ECCX08SelfSignedCert.length()); still not works.
The AT-commands:
Seems there is a problem with some carriers. If you set NB nbAccess=true; and on function getTime() you Serial.println(nbAccess.getTime()); You will find there is printed the following info:
AT+CCLK? +CCLK: "80/01/06,00:00:22"
Since the timestamp returned from carrier is older than the used when generating the certicate will make the error -2 = connection refused.
https://www.unixtimestamp.com/ One workaround is making the function getTime() return the timestamp from the above page (Not Recommended! for production).
Hope this helps Daniel
You could also try to change the sketch to retrieve the time using NTP over UDP: https://github.com/arduino-libraries/MKRNB/blob/master/examples/GPRSUdpNtpClient/GPRSUdpNtpClient.ino
The problem should have been solved months ago. Not month later. The whole solution of your support did not work! Fix the bug...
I had the same issue and it would work perfectly then not??
I think it was disconecting from the network every now and then due to poor signal, and if it happened whilst trying to connect to MQTT it would crash in the while (!mqttClient.connect(broker, 8883))
part of the void mqtt()
code.
I added this to the bottom of the mqtt() while code:
if (nbAccess.status() != NB_READY || gprs.status() != GPRS_READY) {
connectNB();
}
Try changing the while part of your void connectMQTT();
to this:
while (!mqttClient.connect(broker, 8883)) {
// failed, retry
Serial.print(".");
Serial.println(mqttClient.connectError());
delay(5000);
if (nbAccess.status() != NB_READY || gprs.status() != GPRS_READY) {
connectNB();
}
}
Hope that helps.
Hi all,
Iam actually testing the project: Arduino_Cloud_Provider_Examples -> Azure IoT Hub -> Azure_IoT_Hub_NB
In the most cases the "mqttClient.connectError()" returns the value "3". Error-Code for: "MQTT_SERVER_UNAVAILABLE "
Out 1 of 100 tests to connect the mqttClient works fine. Then the connection to the azure-hub is successfully and I can do what I want to send datas to the Azure-Hub. But if I start the sketch again, the mqttclint.connect() shows an error (MQTT_SERVER_UNAVAILABLE) again and then the NB 1500 crashed and hangs up during the loop.
It seems like a problem in the
mqttClient.connect(broker,8883)
. After debugging the sourcecode of NBSSLClient.cpp and NBClient.cpp it shows, that the retry of the loop doesn't work, because the connectio over the SIM-Network cant connect to mqtt-broker or the communication of the network is too slow. (presumable)It's rather strange that it works once and then never again.
The problem can you see in the following pictures: ERRORCODE 3 Successfully connect with mqtt to Azure-Hub
Changes in NBClient.cpp: MODEM.sendf("AT+USOCO=%d,\"%s\",\"%d\",%d", _socket, _host, _port, 1); This change helps to retry after connection failed.
Serial-Output:
CLIENT_STATE_CONNECT, socket: 0 CLIENT_STATE_CONNECT, host: RadarIOT.azure-devices.net CLIENT_STATE_CONNECT, port: 8883 AT+USOCO=0,"RadarIOT.azure-devices.net","8883",1 OK AT+USOWR=0,229,"message" ERROR .0 (int returnValue = mqttClient.connect(broker, 8883);) returns 0 if not connected 3 (mqttClient.connectError() returns 3 if server unavailable Retry
After this change you can see the retry still working but the connect still does not work...
measuring buildung:
Thanks in advance.
Greetings Splitout