Skip to content

Commit 9b1c79e

Browse files
committed
MCU8MASS-1169 Add example for MQTT with connection loss handling
1 parent 28d676c commit 9b1c79e

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/**
2+
* @brief This example demonstrates a more robust MQTT program which takes into
3+
* consideration network disconnection and broker disconnection.
4+
*/
5+
6+
#include <Arduino.h>
7+
8+
#include <ecc608.h>
9+
#include <led_ctrl.h>
10+
#include <log.h>
11+
#include <lte.h>
12+
#include <mcp9808.h>
13+
#include <mqtt_client.h>
14+
#include <sequans_controller.h>
15+
#include <veml3328.h>
16+
17+
#define MQTT_PUB_TOPIC_FMT "%s/sensors"
18+
19+
static char mqtt_pub_topic[128];
20+
21+
static volatile bool connecteded_to_network = false;
22+
static volatile bool connected_to_broker = false;
23+
24+
void connectedToBroker(void) { connected_to_broker = true; }
25+
void disconnectedFromBroker(void) { connected_to_broker = false; }
26+
27+
void disconnectedFromNetwork(void) { connecteded_to_network = false; }
28+
29+
bool initMQTTTopics() {
30+
ECC608.begin();
31+
32+
// Find the thing ID and set the publish and subscription topics
33+
uint8_t thingName[128];
34+
uint8_t thingNameLen = sizeof(thingName);
35+
36+
// -- Get the thingname
37+
uint8_t err = ECC608.getThingName(thingName, &thingNameLen);
38+
if (err != ECC608.ERR_OK) {
39+
Log.error("Could not retrieve thingname from the ECC");
40+
return false;
41+
}
42+
43+
sprintf(mqtt_pub_topic, MQTT_PUB_TOPIC_FMT, thingName);
44+
45+
return true;
46+
}
47+
48+
static bool connectLTE() {
49+
// Connect with a maximum timeout value of 30 000 ms, if the connection is
50+
// not up and running within 30 seconds, abort and retry later
51+
if (!Lte.begin(30000)) {
52+
Log.warn("Failed to connect to operator.");
53+
return false;
54+
} else {
55+
return true;
56+
}
57+
}
58+
59+
static bool connectMqtt() {
60+
61+
uint32_t start = millis();
62+
63+
// Attempt to connect to the broker
64+
if (MqttClient.beginAWS()) {
65+
Log.infof("Connecting to broker");
66+
67+
// Wait for 60 seconds max
68+
while (!MqttClient.isConnected() && millis() - start < 60000) {
69+
Log.rawf(".");
70+
delay(500);
71+
}
72+
73+
if (millis() - start >= 60000) {
74+
Log.rawf(" Failed to connect\r\n");
75+
return false;
76+
}
77+
78+
Log.rawf(" OK!\r\n");
79+
80+
connected_to_broker = true;
81+
} else {
82+
Log.rawf("\r\n");
83+
Log.error("Failed to connect to broker");
84+
85+
return false;
86+
}
87+
88+
return true;
89+
}
90+
91+
void setup() {
92+
Log.begin(115200);
93+
LedCtrl.begin();
94+
LedCtrl.startupCycle();
95+
96+
Log.info("Starting MQTT with Connection Loss Handling\r\n");
97+
98+
if (initMQTTTopics() == false) {
99+
Log.error("Unable to initialize the MQTT topics. Stopping...");
100+
while (1) {}
101+
}
102+
103+
Lte.onDisconnect(disconnectedFromNetwork);
104+
MqttClient.onConnectionStatusChange(connectedToBroker,
105+
disconnectedFromBroker);
106+
107+
SequansController.begin();
108+
109+
SequansController.writeCommand("at+cmee=2");
110+
}
111+
112+
/**
113+
* @brief Used to keep track of the number of publishes.
114+
*/
115+
static uint32_t counter = 0;
116+
117+
/**
118+
* @brief Counts the times the publish has failed due to a timeout.
119+
*/
120+
static uint32_t failed_publishes = 0;
121+
122+
/**
123+
* @brief Used for keeping track of time so that a message is published every
124+
* 10th second under normal operations (when connected to the network and
125+
* broker).
126+
*/
127+
static uint32_t timer = 0;
128+
129+
void loop() {
130+
if (!connecteded_to_network) {
131+
Log.info("Not connected to the network. Attempting to connect!");
132+
if (connectLTE()) {
133+
connecteded_to_network = true;
134+
}
135+
}
136+
137+
if (!connected_to_broker && connecteded_to_network) {
138+
Log.info("Not connected to broker. Attempting to connect!");
139+
140+
if (connectMqtt()) {
141+
connected_to_broker = true;
142+
}
143+
}
144+
145+
if (millis() - timer > 10000) {
146+
if (connected_to_broker) {
147+
char message_to_publish[8] = {0};
148+
sprintf(message_to_publish, "%lu", counter);
149+
150+
bool published_successfully = MqttClient.publish(mqtt_pub_topic,
151+
message_to_publish,
152+
AT_LEAST_ONCE,
153+
60000);
154+
if (published_successfully) {
155+
Log.infof("Published message: %s. Failed publishes: %d.\r\n",
156+
message_to_publish,
157+
failed_publishes);
158+
} else {
159+
failed_publishes++;
160+
}
161+
162+
counter++;
163+
}
164+
165+
timer = millis();
166+
}
167+
}

0 commit comments

Comments
 (0)