1010 *
1111 **************************************************************
1212 * This example connects to AWS IoT Core using MQTT over SSL.
13+ *
14+ * This program writes new certificates to the modem, connects to AWS IoT Core,
15+ * publishes an initial message, and then subscribes to a topic to toggle an
16+ * LED. After the initial connection, the board will check and try to reconnect
17+ * every 10 seconds and republish its status every 60 seconds. If it receives
18+ * any messages on the subscribed topic, it will toggle the LED state. The
19+ * content of any received messages is ignored.
20+ *
21+ * You should run this program once to load your certificates and confirm that
22+ * you can connect to AWS IoT Core over MQTT. Once you have confirmed your
23+ * certificates are loaded and working, there is no reason to rerun this program
24+ * unless you have a new modem, reset your modem, or your certificates change.
25+ * Most modules store the certificates in flash, which has a limited number of
26+ * read/write cycles. To avoid wearing out the flash unnecessarily, you should
27+ * only run this program when necessarily, don't re-write the certificates every
28+ * time you want to connect to AWS IoT Core.
1329 **************************************************************/
1430
1531// Select your modem:
@@ -85,9 +101,7 @@ uint16_t port = 8883;
85101// the client ID should be the name of your "thing" in AWS IoT Core
86102const char * clientId = THING_NAME;
87103
88- static const char topicInit[] TINY_GSM_PROGMEM = THING_NAME " /init" ;
89- static const char msgInit[] TINY_GSM_PROGMEM = " {\" " THING_NAME
90- " \" :\" connected\" }" ;
104+ static const char topicInit[] TINY_GSM_PROGMEM = THING_NAME " /init" ;
91105static const char topicLed[] TINY_GSM_PROGMEM = THING_NAME " /led" ;
92106static const char topicLedStatus[] TINY_GSM_PROGMEM = THING_NAME " /ledStatus" ;
93107
@@ -170,7 +184,7 @@ bool certificateSuccess = false;
170184
171185bool wakeModem () {
172186 // !!!!!!!!!!!
173- // your function to wake and prepare the modem here
187+ // Put your function to wake and prepare the modem here
174188 // !!!!!!!!!!!
175189 return true ;
176190}
@@ -202,16 +216,21 @@ void printModemInfo() {
202216 String modemRevision = modem.getModemRevision ();
203217 SerialMon.print (" Modem Revision: " );
204218 SerialMon.println (modemRevision);
219+ #ifndef TINY_GSM_MODEM_ESP32
205220 String modemSerial = modem.getModemSerialNumber ();
206221 SerialMon.print (" Modem Serial: " );
207222 SerialMon.println (modemSerial);
223+ #endif
208224#if TINY_GSM_USE_GPRS
209225 String modemIMEI = modem.getIMEI ();
210226 SerialMon.print (" Modem IMEI: " );
211227 SerialMon.println (modemIMEI);
212228 String modemIMSI = modem.getIMSI ();
213229 SerialMon.print (" Modem IMSI: " );
214230 SerialMon.println (modemIMSI);
231+ String modemSimCCID = modem.getSimCCID ();
232+ SerialMon.print (" Modem SIM CCID: " );
233+ SerialMon.println (modemSimCCID);
215234#endif
216235}
217236
@@ -234,6 +253,7 @@ bool setupCertificates() {
234253 SerialMon.println (
235254 " Printing Certificate Authority Certificate to confirm it matches" );
236255 modem.printCertificate (root_ca_name, SerialMon);
256+ delay (1000 );
237257 }
238258 // convert the certificate to the modem's format
239259 SerialMon.print (" Converting Certificate Authority Certificate" );
@@ -312,6 +332,65 @@ bool setupCertificates() {
312332#endif
313333}
314334
335+ String createStatusMessage () {
336+ String msgStatus = " {\" clientId\" :\" " THING_NAME " \" " ;
337+ msgStatus += " ,\" LED status\" :\" " + String (ledStatus) + " \" " ;
338+
339+ #if TINY_GSM_USE_GPRS
340+ String modemIMEI = modem.getIMEI ();
341+ msgStatus += " ,\" modemIMEI\" :\" " + modemIMEI + " \" " ;
342+ String modemSimCCID = modem.getSimCCID ();
343+ msgStatus += " ,\" modemSimCCID\" :\" " + modemSimCCID + " \" " ;
344+ #endif
345+
346+ uint16_t modemService = modem.getSignalQuality ();
347+ msgStatus += " ,\" modemSignalQuality\" :\" " + String (modemService) + " \" " ;
348+
349+ #ifdef TINY_GSM_MODEM_HAS_NTP
350+ String time = modem.getGSMDateTime (TinyGSMDateTimeFormat::DATE_FULL);
351+ msgStatus += " ,\" modemTime\" :\" " + time + " \" " ;
352+ #endif
353+ msgStatus += " }" ;
354+ return msgStatus;
355+ }
356+
357+ String createInitMessage () {
358+ String msgInit = " {\" clientId\" :\" " THING_NAME " \" " ;
359+
360+ String modemInfo = modem.getModemInfo ();
361+ msgInit += " ,\" modemInfo\" :\" " + modemInfo + " \" " ;
362+ String modemManufacturer = modem.getModemManufacturer ();
363+ msgInit += " ,\" modemManufacturer\" :\" " + modemManufacturer + " \" " ;
364+ String modemModel = modem.getModemModel ();
365+ msgInit += " ,\" modemModel\" :\" " + modemModel + " \" " ;
366+ String modemRevision = modem.getModemRevision ();
367+ msgInit += " ,\" modemRevision\" :\" " + modemRevision + " \" " ;
368+ #ifndef TINY_GSM_MODEM_ESP32
369+ String modemSerial = modem.getModemSerialNumber ();
370+ msgInit += " ,\" modemSerial\" :\" " + modemSerial + " \" " ;
371+ #endif
372+ #if TINY_GSM_USE_GPRS
373+ String modemIMEI = modem.getIMEI ();
374+ msgInit += " ,\" modemIMEI\" :\" " + modemIMEI + " \" " ;
375+ String modemIMSI = modem.getIMSI ();
376+ msgInit += " ,\" modemIMSI\" :\" " + modemIMSI + " \" " ;
377+ String modemSimCCID = modem.getSimCCID ();
378+ msgInit += " ,\" modemSimCCID\" :\" " + modemSimCCID + " \" " ;
379+ #endif
380+
381+ uint16_t modemService = modem.getSignalQuality ();
382+ msgInit += " ,\" modemSignalQuality\" :\" " + String (modemService) + " \" " ;
383+
384+ #ifdef TINY_GSM_MODEM_HAS_NTP
385+ String time = modem.getGSMDateTime (TinyGSMDateTimeFormat::DATE_FULL);
386+ msgInit += " ,\" modemTime\" :\" " + time + " \" " ;
387+ #endif
388+
389+ msgInit += " }" ;
390+
391+ return msgInit;
392+ }
393+
315394void mqttCallback (char * topic, byte* payload, unsigned int len) {
316395 SerialMon.print (" Message arrived [" );
317396 SerialMon.print (topic);
@@ -323,11 +402,10 @@ void mqttCallback(char* topic, byte* payload, unsigned int len) {
323402 if (String (topic) == topicLed) {
324403 ledStatus = !ledStatus;
325404 digitalWrite (LED_PIN, ledStatus);
326- if (ledStatus) {
327- mqtt.publish (topicLedStatus, " {\" LED status\" :\" 1\" }" );
328- } else {
329- mqtt.publish (topicLedStatus, " {\" LED status\" :\" 0\" }" );
330- }
405+
406+ // Create a status message to send to the broker
407+ String msgStatus = createStatusMessage ();
408+ mqtt.publish (topicLedStatus, msgStatus.c_str ());
331409 }
332410}
333411
@@ -346,9 +424,27 @@ bool mqttConnect() {
346424 }
347425 SerialMon.println (" ...success" );
348426
427+ // Create a init message to send to the broker
428+ String msgInit = createInitMessage ();
429+
430+ // Make sure the MQTT buffer is large enough to hold the
431+ // initial message and the topic name.
432+ uint16_t neededBuffer = MQTT_MAX_HEADER_SIZE + 2 +
433+ strnlen (topicInit, mqtt.getBufferSize ()) + msgInit.length () + 1 ;
434+ if (mqtt.getBufferSize () < neededBuffer) {
435+ SerialMon.print (" Increasing MQTT buffer size from " );
436+ SerialMon.print (mqtt.getBufferSize ());
437+ SerialMon.print (" to " );
438+ SerialMon.println (neededBuffer);
439+ mqtt.setBufferSize (neededBuffer);
440+ }
441+
349442 SerialMon.print (" Publishing a message to " );
350443 SerialMon.println (topicInit);
351- bool got_pub = mqtt.publish (topicInit, msgInit);
444+ SerialMon.print (" Message content: " );
445+ SerialMon.println (msgInit);
446+
447+ bool got_pub = mqtt.publish (topicInit, msgInit.c_str ());
352448 SerialMon.println (got_pub ? " published" : " failed to publish" );
353449 SerialMon.print (" Subscribing to " );
354450 SerialMon.println (topicLed);
@@ -362,12 +458,9 @@ bool mqttPublishStatus() {
362458 SerialMon.print (" Publishing a message to " );
363459 SerialMon.println (topicLedStatus);
364460
365- bool got_pub = false ;
366- if (ledStatus) {
367- got_pub = mqtt.publish (topicLedStatus, " {\" LED status\" :\" 1\" }" );
368- } else {
369- got_pub = mqtt.publish (topicLedStatus, " {\" LED status\" :\" 0\" }" );
370- }
461+ // Create a status message to send to the broker
462+ String msgStatus = createStatusMessage ();
463+ bool got_pub = mqtt.publish (topicLedStatus, msgStatus.c_str ());
371464
372465 SerialMon.println (got_pub ? " published" : " failed to publish" );
373466 return got_pub;
@@ -388,15 +481,14 @@ bool setupModem() {
388481 SerialMon.print (" Initializing modem..." );
389482 if (!modem.init ()) { // modem.restart();
390483 SerialMon.println (" ...failed to initialize modem!" );
391- delay (30000 );
484+ delay (15000L );
392485 return false ;
393486 }
394487 SerialMon.println (" ...success" );
395488
396489 // Max out the baud rate, if desired
397490 // NOTE: Do this **AFTER** the modem has been restarted - many modules
398- // revert to default baud rates when reset or powered off. 921600, 460800,
399- // 230400, 115200
491+ // revert to default baud rates when reset or powered off.
400492 success &= setModemBaud (115200 );
401493
402494 printModemInfo ();
@@ -439,13 +531,14 @@ bool setupNetwork() {
439531}
440532
441533bool getInternetConnection () {
442- // Make sure we're registered on the network
534+ // Make sure we're connected to or registered on the network
443535 // For Wi-Fi this is all we need to do
444536 if (!modem.isNetworkConnected ()) {
445537 SerialMon.println (" Network disconnected" );
446- if (!modem.waitForNetwork (180000L , true )) {
538+ SerialMon.println (" Waiting up to 5 minutes for network connection..." );
539+ if (!modem.waitForNetwork (300000L , true )) {
447540 SerialMon.println (" ...failed to reconnect to network!" );
448- delay (30000 );
541+ delay (15000L );
449542 return false ;
450543 }
451544 if (modem.isNetworkConnected ()) { SerialMon.println (" Network connected" ); }
@@ -461,7 +554,7 @@ bool getInternetConnection() {
461554 SerialMon.println (apn);
462555 if (!modem.gprsConnect (apn, gprsUser, gprsPass)) {
463556 SerialMon.println (" ...failed to connect to GPRS!" );
464- delay (30000 );
557+ delay (15000L );
465558 return false ;
466559 }
467560 if (modem.isGprsConnected ()) { SerialMon.println (" GPRS reconnected" ); }
@@ -495,7 +588,8 @@ void setup() {
495588
496589 // MQTT Broker setup
497590 // NOTE: This is only configuring the server and callback within the
498- // PubSubClient object. It does not take any action.
591+ // PubSubClient object.
592+ // It does not take any action.
499593 mqtt.setServer (broker, port);
500594 mqtt.setCallback (mqttCallback);
501595
@@ -511,7 +605,7 @@ void setup() {
511605 setupSuccess = setupModem ();
512606 if (!setupSuccess) {
513607 SerialMon.println (" ...failed to set up modem!" );
514- delay (30000 );
608+ delay (15000L );
515609 return ;
516610 }
517611 SerialMon.println (" ...success" );
@@ -520,15 +614,15 @@ void setup() {
520614 certificateSuccess = setupCertificates ();
521615 if (!certificateSuccess) {
522616 SerialMon.println (" ...failed to set up certificates!" );
523- delay (30000 );
617+ delay (15000L );
524618 return ;
525619 }
526620 SerialMon.println (" ...success" );
527621
528622 SerialMon.println (" Setting up network..." );
529623 if (!setupNetwork ()) {
530624 SerialMon.println (" ...failed to set up network!" );
531- delay (30000 );
625+ delay (15000L );
532626 return ;
533627 }
534628 SerialMon.println (" ...success" );
@@ -545,7 +639,7 @@ void loop() {
545639 setupSuccess = setupModem ();
546640 if (!setupSuccess) {
547641 SerialMon.println (" ...failed to set up modem!" );
548- delay (30000 );
642+ delay (15000L );
549643 return ;
550644 }
551645 SerialMon.println (" ...success" );
@@ -556,7 +650,7 @@ void loop() {
556650 certificateSuccess = setupCertificates ();
557651 if (!certificateSuccess) {
558652 SerialMon.println (" ...failed to set up certificates!" );
559- delay (30000 );
653+ delay (15000L );
560654 return ;
561655 }
562656 SerialMon.println (" ...success" );
0 commit comments