BG96 Module MQTT client example using X-NUCLEO-IKS01A2

Dependencies:   mbed X_NUCLEO_IKS01A2 NetworkSocketAPI MQTT

Getting started mbed NbIot with BG96 module

NbIot BG96 board Main features:

  • LTE/EDGE modem for IOT connection
  • 4A type Pmod interface (expanded uart) except for signals on pin 1 (MODEM RING) and pin 4 (MODEM POWER KEY) here below schematics of pmod connector /media/uploads/abci5961/pmod_sch.jpg

/media/uploads/abci5961/hw_details.jpg

Using USB - AT command port and RealTerm for AT command line

  • Connect the BG96 board to the PC using USB port,

Warning

How to power up BG96 in USB-AT standalone

If you like to use the board STAND-ALONE ( USB - AT port), you must manually power up th BG96 modem. To make this:

  1. Connect the USB
  2. Make a short connection between pin 5 of ARDUINO POWER and pin 4 of PMOD to enable BG96_PWRKEY_ACTIVE_HIGH ( on the rev.C of the board we will add a pushbutton to make this easy )
  3. After short time the blue led start flashing
  4. After a short time the USB will be active and ( you need Quectel drivers )
  5. com port are now shown on the PC

/media/uploads/abci5961/bg96_start_from_usb_a.jpg

  • Open RealTerm and configure as follow: /media/uploads/abci5961/real_term.jpg
  • try to send "AT" command and see the "OK" answer from BG96
  • try any other command from BG96 AT user's guide /media/uploads/abci5961/at_command.jpg

NbIot BG96 MQTT Client example

for mbed OS online Compiler or user's IDE toolchain

It demonstrates how register and send data of some sensor to IBM BlueMix MQTT Quickstart server. It also can connect with MyBlueMix Avnet server (to make this user must have credential to log into Avnet server)

Please note that this example was derived from original IDW01M1_Cloud_IBM for WiFi connections. The WIFI original project can be found here

The application, by default:

  • Connects to LTE network via BG96
  • opens a UDP socket to Google DNS to obtain ip address of Quickstart server
  • opens a TCP socket to Quickstart server to register and send data
  • Send, every 30 seconds, local sensors data (temperature, humidity, pressure)

Hardware requirement

  • X_NUCLEO_L476RG mcu board
  • X_NUCLEO_IKS01A2 sensors expansion board
  • AVNET RSR1157 NbIOT BG96 expansion board

/media/uploads/abci5961/hw_req_1.jpg

BG96 Mqtt client example User's Guide here

Committer:
abci5961
Date:
Fri Nov 17 17:23:30 2017 +0100
Revision:
0:ae6c6727b545
Child:
1:a622606a49fd
First release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
abci5961 0:ae6c6727b545 1 /* BG96 NetworkSocketAPI Example Program
abci5961 0:ae6c6727b545 2 * Copyright (c) 2015 ARM Limited
abci5961 0:ae6c6727b545 3 *
abci5961 0:ae6c6727b545 4 * Licensed under the Apache License, Version 2.0 (the "License");
abci5961 0:ae6c6727b545 5 * you may not use this file except in compliance with the License.
abci5961 0:ae6c6727b545 6 * You may obtain a copy of the License at
abci5961 0:ae6c6727b545 7 *
abci5961 0:ae6c6727b545 8 * http://www.apache.org/licenses/LICENSE-2.0
abci5961 0:ae6c6727b545 9 *
abci5961 0:ae6c6727b545 10 * Unless required by applicable law or agreed to in writing, software
abci5961 0:ae6c6727b545 11 * distributed under the License is distributed on an "AS IS" BASIS,
abci5961 0:ae6c6727b545 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
abci5961 0:ae6c6727b545 13 * See the License for the specific language governing permissions and
abci5961 0:ae6c6727b545 14 * limitations under the License.
abci5961 0:ae6c6727b545 15 */
abci5961 0:ae6c6727b545 16
abci5961 0:ae6c6727b545 17 #include "mbed.h"
abci5961 0:ae6c6727b545 18 #include "BG96Interface.h"
abci5961 0:ae6c6727b545 19 #include "TCPSocket.h"
abci5961 0:ae6c6727b545 20 #include "MQTTClient.h"
abci5961 0:ae6c6727b545 21 #include "MQTT_GSM.h"
abci5961 0:ae6c6727b545 22 #include <ctype.h>
abci5961 0:ae6c6727b545 23 //#include "x_nucleo_iks01a1.h"
abci5961 0:ae6c6727b545 24 #include "XNucleoIKS01A2.h"
abci5961 0:ae6c6727b545 25
abci5961 0:ae6c6727b545 26 #include "BG96.h"
abci5961 0:ae6c6727b545 27
abci5961 0:ae6c6727b545 28 //------------------------------------
abci5961 0:ae6c6727b545 29 // Hyperterminal default configuration
abci5961 0:ae6c6727b545 30 // 9600 bauds, 8-bit data, no parity
abci5961 0:ae6c6727b545 31 //------------------------------------
abci5961 0:ae6c6727b545 32 Serial pc(SERIAL_TX, SERIAL_RX);
abci5961 0:ae6c6727b545 33 DigitalOut myled(LED1);
abci5961 0:ae6c6727b545 34 bool quickstartMode = true;
abci5961 0:ae6c6727b545 35
abci5961 0:ae6c6727b545 36 #define MQTT_MAX_PACKET_SIZE 300
abci5961 0:ae6c6727b545 37 #define MQTT_MAX_PAYLOAD_SIZE 500
abci5961 0:ae6c6727b545 38
abci5961 0:ae6c6727b545 39
abci5961 0:ae6c6727b545 40 #define ORG_QUICKSTART // comment to connect to play.internetofthings.ibmcloud.com
abci5961 0:ae6c6727b545 41 //#define SUBSCRIBE // uncomment to subscribe to broker msgs (not to be used with IBM broker)
abci5961 0:ae6c6727b545 42
abci5961 0:ae6c6727b545 43 // Configuration values needed to connect to IBM IoT Cloud
abci5961 0:ae6c6727b545 44 #define BROKER_URL ".messaging.internetofthings.ibmcloud.com";
abci5961 0:ae6c6727b545 45 #ifdef ORG_QUICKSTART
abci5961 0:ae6c6727b545 46 #define ORG "quickstart" // connect to quickstart.internetofthings.ibmcloud.com/ For a registered connection, replace with your org
abci5961 0:ae6c6727b545 47 #define ID ""
abci5961 0:ae6c6727b545 48 #define AUTH_TOKEN ""
abci5961 0:ae6c6727b545 49 #define DEFAULT_TYPE_NAME "iotsample-mbed-Nucleo"
abci5961 0:ae6c6727b545 50 #define TOPIC "iot-2/evt/status/fmt/json"
abci5961 0:ae6c6727b545 51 #else // not def ORG_QUICKSTART
abci5961 0:ae6c6727b545 52 #define ORG "pvko17" // connect to play.internetofthings.ibmcloud.com/ For a registered connection, replace with your org
abci5961 0:ae6c6727b545 53 #define ID "testtype_112233445566" // For a registered connection, replace with your id
abci5961 0:ae6c6727b545 54 #define AUTH_TOKEN "testtype_112233445566" // For a registered connection, replace with your auth-token
abci5961 0:ae6c6727b545 55 #define DEFAULT_TYPE_NAME "TestType"
abci5961 0:ae6c6727b545 56 #define TOPIC "iot-2/type/TestType/id/testtype_112233445566/evt/status/fmt/json"
abci5961 0:ae6c6727b545 57 #endif
abci5961 0:ae6c6727b545 58
abci5961 0:ae6c6727b545 59 // network credential
abci5961 0:ae6c6727b545 60 //#define APN "web.omnitel.it" //VODAFONE apn definition's
abci5961 0:ae6c6727b545 61 #define APN "internet.wind" //WIND apn definition's
abci5961 0:ae6c6727b545 62 #define PASSW ""
abci5961 0:ae6c6727b545 63 #define USNAME ""
abci5961 0:ae6c6727b545 64
abci5961 0:ae6c6727b545 65 #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type
abci5961 0:ae6c6727b545 66 #define MQTT_PORT 1883
abci5961 0:ae6c6727b545 67 #define MQTT_TLS_PORT 8883
abci5961 0:ae6c6727b545 68 #define IBM_IOT_PORT MQTT_PORT
abci5961 0:ae6c6727b545 69
abci5961 0:ae6c6727b545 70 char id[30] = ID; // mac without colons
abci5961 0:ae6c6727b545 71 char org[12] = ORG;
abci5961 0:ae6c6727b545 72 int connack_rc = 0; // MQTT connack return code
abci5961 0:ae6c6727b545 73 //const char* ip_addr = "11.12.13.14";
abci5961 0:ae6c6727b545 74 //char* host_addr = "11.12.13.14";
abci5961 0:ae6c6727b545 75 char sensor_id[50];
abci5961 0:ae6c6727b545 76 char type[30] = TYPE;
abci5961 0:ae6c6727b545 77 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
abci5961 0:ae6c6727b545 78 bool netConnecting = false;
abci5961 0:ae6c6727b545 79 int connectTimeout = 1000;
abci5961 0:ae6c6727b545 80 bool mqttConnecting = false;
abci5961 0:ae6c6727b545 81 bool netConnected = false;
abci5961 0:ae6c6727b545 82 bool connected = false;
abci5961 0:ae6c6727b545 83 int retryAttempt = 0;
abci5961 0:ae6c6727b545 84 char subscription_url[MQTT_MAX_PAYLOAD_SIZE];
abci5961 0:ae6c6727b545 85
abci5961 0:ae6c6727b545 86 #define SENSOR_ENABLED 1
abci5961 0:ae6c6727b545 87 #define SENSOR_MODEL 2
abci5961 0:ae6c6727b545 88
abci5961 0:ae6c6727b545 89 #define FW_REV "1.0a"
abci5961 0:ae6c6727b545 90
abci5961 0:ae6c6727b545 91 PressureSensor *pressure_sensor;
abci5961 0:ae6c6727b545 92 HumiditySensor *humidity_sensor;
abci5961 0:ae6c6727b545 93 TempSensor *temp_sensor1;
abci5961 0:ae6c6727b545 94
abci5961 0:ae6c6727b545 95 MQTT::Message message;
abci5961 0:ae6c6727b545 96 MQTTString TopicName={TOPIC};
abci5961 0:ae6c6727b545 97 MQTT::MessageData MsgData(TopicName, message);
abci5961 0:ae6c6727b545 98
abci5961 0:ae6c6727b545 99
abci5961 0:ae6c6727b545 100 //#if SENSOR_ENABLED
abci5961 0:ae6c6727b545 101 //#if SENSOR_MODEL == 2
abci5961 0:ae6c6727b545 102
abci5961 0:ae6c6727b545 103 /* Instantiate the expansion board */
abci5961 0:ae6c6727b545 104 static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5);
abci5961 0:ae6c6727b545 105
abci5961 0:ae6c6727b545 106 /* Retrieve the composing elements of the expansion board */
abci5961 0:ae6c6727b545 107 static LSM303AGRMagSensor *magnetometer = mems_expansion_board->magnetometer;
abci5961 0:ae6c6727b545 108 static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor;
abci5961 0:ae6c6727b545 109 static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor;
abci5961 0:ae6c6727b545 110 static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro;
abci5961 0:ae6c6727b545 111 static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer;
abci5961 0:ae6c6727b545 112 //#endif
abci5961 0:ae6c6727b545 113 //#endif
abci5961 0:ae6c6727b545 114
abci5961 0:ae6c6727b545 115 void subscribe_cb(MQTT::MessageData & msgMQTT) {
abci5961 0:ae6c6727b545 116 char msg[MQTT_MAX_PAYLOAD_SIZE];
abci5961 0:ae6c6727b545 117 msg[0]='\0';
abci5961 0:ae6c6727b545 118 strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen);
abci5961 0:ae6c6727b545 119 printf ("--->>> subscribe_cb msg: %s\n\r", msg);
abci5961 0:ae6c6727b545 120 }
abci5961 0:ae6c6727b545 121
abci5961 0:ae6c6727b545 122 int subscribe(MQTT::Client<MQTT_GSM, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTT_GSM* ipstack)
abci5961 0:ae6c6727b545 123 {
abci5961 0:ae6c6727b545 124 char* pubTopic = TOPIC;
abci5961 0:ae6c6727b545 125 return client->subscribe(pubTopic, MQTT::QOS1, subscribe_cb);
abci5961 0:ae6c6727b545 126 }
abci5961 0:ae6c6727b545 127
abci5961 0:ae6c6727b545 128 int connect(MQTT::Client<MQTT_GSM, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTT_GSM* ipstack)
abci5961 0:ae6c6727b545 129 {
abci5961 0:ae6c6727b545 130 const char* iot_ibm = BROKER_URL;
abci5961 0:ae6c6727b545 131
abci5961 0:ae6c6727b545 132
abci5961 0:ae6c6727b545 133 char hostname[strlen(org) + strlen(iot_ibm) + 1];
abci5961 0:ae6c6727b545 134 sprintf(hostname, "%s%s", org, iot_ibm);
abci5961 0:ae6c6727b545 135
abci5961 0:ae6c6727b545 136
abci5961 0:ae6c6727b545 137 // Construct clientId - d:org:type:id
abci5961 0:ae6c6727b545 138 char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
abci5961 0:ae6c6727b545 139
abci5961 0:ae6c6727b545 140 #ifdef ORG_QUICKSTART
abci5961 0:ae6c6727b545 141 sprintf(clientId, "d:%s:%s:%s", org, type, id); //@@
abci5961 0:ae6c6727b545 142 #else
abci5961 0:ae6c6727b545 143 sprintf(clientId, "g:%s:%s:%s", org, type, id); //@@
abci5961 0:ae6c6727b545 144 #endif
abci5961 0:ae6c6727b545 145
abci5961 0:ae6c6727b545 146 sprintf(subscription_url, "%s.%s/#/device/%s/sensor/", org, "internetofthings.ibmcloud.com",id);
abci5961 0:ae6c6727b545 147
abci5961 0:ae6c6727b545 148 netConnecting = true;
abci5961 0:ae6c6727b545 149 ipstack->open(&ipstack->getGSM());
abci5961 0:ae6c6727b545 150 int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout);
abci5961 0:ae6c6727b545 151 if (rc != 0)
abci5961 0:ae6c6727b545 152 {
abci5961 0:ae6c6727b545 153 //WARN("IP Stack connect returned: %d\n", rc);
abci5961 0:ae6c6727b545 154 return rc;
abci5961 0:ae6c6727b545 155 }
abci5961 0:ae6c6727b545 156 pc.printf ("--->TCP Connected\n\r");
abci5961 0:ae6c6727b545 157 netConnected = true;
abci5961 0:ae6c6727b545 158 netConnecting = false;
abci5961 0:ae6c6727b545 159
abci5961 0:ae6c6727b545 160 // MQTT Connect
abci5961 0:ae6c6727b545 161 mqttConnecting = true;
abci5961 0:ae6c6727b545 162 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
abci5961 0:ae6c6727b545 163 data.MQTTVersion = 3;
abci5961 0:ae6c6727b545 164 data.struct_version=0;
abci5961 0:ae6c6727b545 165 data.clientID.cstring = clientId;
abci5961 0:ae6c6727b545 166
abci5961 0:ae6c6727b545 167 if (!quickstartMode)
abci5961 0:ae6c6727b545 168 {
abci5961 0:ae6c6727b545 169 data.username.cstring = "use-token-auth";
abci5961 0:ae6c6727b545 170 data.password.cstring = auth_token;
abci5961 0:ae6c6727b545 171 }
abci5961 0:ae6c6727b545 172 if ((rc = client->connect(data)) == 0)
abci5961 0:ae6c6727b545 173 {
abci5961 0:ae6c6727b545 174 connected = true;
abci5961 0:ae6c6727b545 175 pc.printf ("--->MQTT Connected\n\r");
abci5961 0:ae6c6727b545 176 #ifdef SUBSCRIBE
abci5961 0:ae6c6727b545 177 if (!subscribe(client, ipstack)) printf ("--->>>MQTT subscribed to: %s\n\r",TOPIC);
abci5961 0:ae6c6727b545 178 #endif
abci5961 0:ae6c6727b545 179 }
abci5961 0:ae6c6727b545 180 else {
abci5961 0:ae6c6727b545 181 //WARN("MQTT connect returned %d\n", rc);
abci5961 0:ae6c6727b545 182 }
abci5961 0:ae6c6727b545 183 if (rc >= 0)
abci5961 0:ae6c6727b545 184 connack_rc = rc;
abci5961 0:ae6c6727b545 185 mqttConnecting = false;
abci5961 0:ae6c6727b545 186 return rc;
abci5961 0:ae6c6727b545 187 }
abci5961 0:ae6c6727b545 188
abci5961 0:ae6c6727b545 189 int getConnTimeout(int attemptNumber)
abci5961 0:ae6c6727b545 190 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
abci5961 0:ae6c6727b545 191 // after 20 attempts, retry every 10 minutes
abci5961 0:ae6c6727b545 192 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
abci5961 0:ae6c6727b545 193 }
abci5961 0:ae6c6727b545 194
abci5961 0:ae6c6727b545 195 void attemptConnect(MQTT::Client<MQTT_GSM, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTT_GSM* ipstack)
abci5961 0:ae6c6727b545 196 {
abci5961 0:ae6c6727b545 197 connected = false;
abci5961 0:ae6c6727b545 198
abci5961 0:ae6c6727b545 199 while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED)
abci5961 0:ae6c6727b545 200 {
abci5961 0:ae6c6727b545 201 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) {
abci5961 0:ae6c6727b545 202 printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc);
abci5961 0:ae6c6727b545 203 return; // don't reattempt to connect if credentials are wrong
abci5961 0:ae6c6727b545 204 }
abci5961 0:ae6c6727b545 205 int timeout = getConnTimeout(++retryAttempt);
abci5961 0:ae6c6727b545 206 //WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
abci5961 0:ae6c6727b545 207
abci5961 0:ae6c6727b545 208 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
abci5961 0:ae6c6727b545 209 // or maybe just add the proper members to do this disconnect and call attemptConnect(...)
abci5961 0:ae6c6727b545 210 // this works - reset the system when the retry count gets to a threshold
abci5961 0:ae6c6727b545 211 if (retryAttempt == 5){
abci5961 0:ae6c6727b545 212 pc.printf ("\n\n\rFAIL!! system reset!!\n\n\r");
abci5961 0:ae6c6727b545 213 NVIC_SystemReset();
abci5961 0:ae6c6727b545 214 }
abci5961 0:ae6c6727b545 215 else
abci5961 0:ae6c6727b545 216 wait(timeout);
abci5961 0:ae6c6727b545 217 }
abci5961 0:ae6c6727b545 218 }
abci5961 0:ae6c6727b545 219 float hum_global = 50.0;
abci5961 0:ae6c6727b545 220 uint32_t n_msg = 0;
abci5961 0:ae6c6727b545 221
abci5961 0:ae6c6727b545 222 int publish(MQTT::Client<MQTT_GSM, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTT_GSM* ipstack)
abci5961 0:ae6c6727b545 223 {
abci5961 0:ae6c6727b545 224 MQTT::Message message;
abci5961 0:ae6c6727b545 225 char* pubTopic = TOPIC;
abci5961 0:ae6c6727b545 226
abci5961 0:ae6c6727b545 227 char buf[MQTT_MAX_PAYLOAD_SIZE];
abci5961 0:ae6c6727b545 228 float temp, temp1, temp2, press, hum;
abci5961 0:ae6c6727b545 229
abci5961 0:ae6c6727b545 230 #if SENSOR_ENABLED
abci5961 0:ae6c6727b545 231 pc.printf("reading sensors...");
abci5961 0:ae6c6727b545 232 #if SENSOR_MODEL == 1
abci5961 0:ae6c6727b545 233 temp_sensor1->GetTemperature(&temp);
abci5961 0:ae6c6727b545 234 pressure_sensor->GetPressure(&press);
abci5961 0:ae6c6727b545 235 humidity_sensor->GetHumidity(&hum);
abci5961 0:ae6c6727b545 236 #endif
abci5961 0:ae6c6727b545 237
abci5961 0:ae6c6727b545 238 #if SENSOR_MODEL == 2
abci5961 0:ae6c6727b545 239 hum_temp->get_temperature(&temp1);
abci5961 0:ae6c6727b545 240 hum_temp->get_humidity(&hum);
abci5961 0:ae6c6727b545 241
abci5961 0:ae6c6727b545 242 press_temp->get_temperature(&temp2);
abci5961 0:ae6c6727b545 243 press_temp->get_pressure(&press);
abci5961 0:ae6c6727b545 244 temp = (temp1+temp2)/2;
abci5961 0:ae6c6727b545 245 #endif
abci5961 0:ae6c6727b545 246
abci5961 0:ae6c6727b545 247 pc.printf(" DONE\r\n");
abci5961 0:ae6c6727b545 248 #else
abci5961 0:ae6c6727b545 249 temp=25.5;
abci5961 0:ae6c6727b545 250 hum_global +=0.1;
abci5961 0:ae6c6727b545 251 if (hum_global>99.0)
abci5961 0:ae6c6727b545 252 hum_global = 50.0;
abci5961 0:ae6c6727b545 253 hum=hum_global;
abci5961 0:ae6c6727b545 254 press=999;
abci5961 0:ae6c6727b545 255 #endif
abci5961 0:ae6c6727b545 256
abci5961 0:ae6c6727b545 257 #ifdef ORG_QUICKSTART
abci5961 0:ae6c6727b545 258 sprintf(buf,
abci5961 0:ae6c6727b545 259 "{\"d\":{\"ST\":\"Nucleo-IoT-mbed\",\"Temp\":%0.4f,\"Pressure\":%0.4f,\"Humidity\":%0.4f}}",
abci5961 0:ae6c6727b545 260 temp, press, hum);
abci5961 0:ae6c6727b545 261 #else
abci5961 0:ae6c6727b545 262 sprintf (buf,
abci5961 0:ae6c6727b545 263 "{\"%s\": {\"temp\":%0.4f,\"humidity\":%0.4f,\"pressure\":%0.4f,\"ambient\":0,\"uv\":0,\"accel_X\":0,\"accel_Y\":0,\"accel_Z\":0}}",
abci5961 0:ae6c6727b545 264 sensor_id, temp, hum, press);
abci5961 0:ae6c6727b545 265 #endif
abci5961 0:ae6c6727b545 266
abci5961 0:ae6c6727b545 267 message.qos = MQTT::QOS0;
abci5961 0:ae6c6727b545 268 message.retained = false;
abci5961 0:ae6c6727b545 269 message.dup = false;
abci5961 0:ae6c6727b545 270 message.payload = (void*)buf;
abci5961 0:ae6c6727b545 271 message.payloadlen = strlen(buf);
abci5961 0:ae6c6727b545 272
abci5961 0:ae6c6727b545 273 //LOG("Publishing %s\n\r", buf);
abci5961 0:ae6c6727b545 274 n_msg++;
abci5961 0:ae6c6727b545 275 pc.printf("Publishing V%s #%d %s\n\r", FW_REV, n_msg, buf);
abci5961 0:ae6c6727b545 276 return client->publish(pubTopic, message);
abci5961 0:ae6c6727b545 277 }
abci5961 0:ae6c6727b545 278
abci5961 0:ae6c6727b545 279
abci5961 0:ae6c6727b545 280 int loop_count = 0;
abci5961 0:ae6c6727b545 281 void test_sens(void);
abci5961 0:ae6c6727b545 282
abci5961 0:ae6c6727b545 283 int main()
abci5961 0:ae6c6727b545 284 {
abci5961 0:ae6c6727b545 285 const char * apn = APN; // Network must be visible otherwise it can't connect
abci5961 0:ae6c6727b545 286 const char * username = USNAME;
abci5961 0:ae6c6727b545 287 const char * password = PASSW;
abci5961 0:ae6c6727b545 288 BG96Interface bg96_if(D8, D2, false);
abci5961 0:ae6c6727b545 289 //sprintf(sensor_id,"%s",bg96_if.get_mac_address());
abci5961 0:ae6c6727b545 290 //Timer tyeld;
abci5961 0:ae6c6727b545 291
abci5961 0:ae6c6727b545 292 //change serial baud to 115200
abci5961 0:ae6c6727b545 293 pc.baud(115200);
abci5961 0:ae6c6727b545 294 wait(0.1);
abci5961 0:ae6c6727b545 295
abci5961 0:ae6c6727b545 296 myled=1;
abci5961 0:ae6c6727b545 297 //wait(0.5);
abci5961 0:ae6c6727b545 298 pc.printf("\r\n*************************************************");
abci5961 0:ae6c6727b545 299 wait( 0.1 );
abci5961 0:ae6c6727b545 300 pc.printf("\r\nAvnet Silica NbIotBG96 mbed-os application\r\n");
abci5961 0:ae6c6727b545 301 wait( 0.1 );
abci5961 0:ae6c6727b545 302 pc.printf("MBED online version %s\r\n", FW_REV);
abci5961 0:ae6c6727b545 303 wait( 0.1 );
abci5961 0:ae6c6727b545 304 //pc.printf("\r\nwait for APN ready ...\r\n");
abci5961 0:ae6c6727b545 305 //wait( 0.1 );
abci5961 0:ae6c6727b545 306
abci5961 0:ae6c6727b545 307 #if SENSOR_ENABLED
abci5961 0:ae6c6727b545 308 #if SENSOR_MODEL == 1
abci5961 0:ae6c6727b545 309 DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL);
abci5961 0:ae6c6727b545 310 i2c->frequency(400000);
abci5961 0:ae6c6727b545 311
abci5961 0:ae6c6727b545 312 X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(i2c);
abci5961 0:ae6c6727b545 313 pressure_sensor = mems_expansion_board->pt_sensor;
abci5961 0:ae6c6727b545 314 temp_sensor1 = mems_expansion_board->ht_sensor;
abci5961 0:ae6c6727b545 315 humidity_sensor = mems_expansion_board->ht_sensor;
abci5961 0:ae6c6727b545 316 #endif
abci5961 0:ae6c6727b545 317
abci5961 0:ae6c6727b545 318 #if SENSOR_MODEL == 2
abci5961 0:ae6c6727b545 319 /* Enable all sensors */
abci5961 0:ae6c6727b545 320 hum_temp->enable();
abci5961 0:ae6c6727b545 321 press_temp->enable();
abci5961 0:ae6c6727b545 322 //magnetometer->enable();
abci5961 0:ae6c6727b545 323 //accelerometer->enable();
abci5961 0:ae6c6727b545 324 //acc_gyro->enable_x();
abci5961 0:ae6c6727b545 325 //acc_gyro->enable_g();
abci5961 0:ae6c6727b545 326 #endif
abci5961 0:ae6c6727b545 327 #endif
abci5961 0:ae6c6727b545 328
abci5961 0:ae6c6727b545 329
abci5961 0:ae6c6727b545 330 quickstartMode=false;
abci5961 0:ae6c6727b545 331 if (strcmp(org, "quickstart") == 0){quickstartMode = true;}
abci5961 0:ae6c6727b545 332 MQTT_GSM ipstack(bg96_if, apn, username, password);
abci5961 0:ae6c6727b545 333 MQTT::Client<MQTT_GSM, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
abci5961 0:ae6c6727b545 334 if (quickstartMode){
abci5961 0:ae6c6727b545 335 char mac[50]; // remove all : from mac
abci5961 0:ae6c6727b545 336 char *digit=NULL;
abci5961 0:ae6c6727b545 337 sprintf (id,"%s", "");
abci5961 0:ae6c6727b545 338 sprintf (mac,"%s",ipstack.getGSM().get_mac_address());
abci5961 0:ae6c6727b545 339 digit = strtok (mac,":");
abci5961 0:ae6c6727b545 340 while (digit != NULL)
abci5961 0:ae6c6727b545 341 {
abci5961 0:ae6c6727b545 342 strcat (id, digit);
abci5961 0:ae6c6727b545 343 digit = strtok (NULL, ":");
abci5961 0:ae6c6727b545 344 }
abci5961 0:ae6c6727b545 345 }
abci5961 0:ae6c6727b545 346 attemptConnect(&client, &ipstack);
abci5961 0:ae6c6727b545 347 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD)
abci5961 0:ae6c6727b545 348 {
abci5961 0:ae6c6727b545 349 while (true)
abci5961 0:ae6c6727b545 350 wait(1.0); // Permanent failures - don't retry
abci5961 0:ae6c6727b545 351 }
abci5961 0:ae6c6727b545 352 myled=0;
abci5961 0:ae6c6727b545 353 sprintf(sensor_id,"%s",bg96_if.get_mac_address());
abci5961 0:ae6c6727b545 354
abci5961 0:ae6c6727b545 355 while (true)
abci5961 0:ae6c6727b545 356 {
abci5961 0:ae6c6727b545 357 if (++loop_count == 60)
abci5961 0:ae6c6727b545 358 {
abci5961 0:ae6c6727b545 359 // Publish a message every 30 second
abci5961 0:ae6c6727b545 360 pc.printf("\n");
abci5961 0:ae6c6727b545 361 myled=1;
abci5961 0:ae6c6727b545 362 if (publish(&client, &ipstack) != 0) {
abci5961 0:ae6c6727b545 363 myled=0;
abci5961 0:ae6c6727b545 364 attemptConnect(&client, &ipstack); // if we have lost the connection
abci5961 0:ae6c6727b545 365 }
abci5961 0:ae6c6727b545 366 //else
abci5961 0:ae6c6727b545 367 myled=0;
abci5961 0:ae6c6727b545 368 loop_count = 0;
abci5961 0:ae6c6727b545 369 }
abci5961 0:ae6c6727b545 370 // int start = tyeld.read_ms();
abci5961 0:ae6c6727b545 371 client.yield(500); // allow the MQTT client to receive messages
abci5961 0:ae6c6727b545 372 pc.printf ("loop %d\r", (loop_count+1)); //: %d\n\r",tyeld.read_ms()-start);
abci5961 0:ae6c6727b545 373
abci5961 0:ae6c6727b545 374 }
abci5961 0:ae6c6727b545 375
abci5961 0:ae6c6727b545 376 }
abci5961 0:ae6c6727b545 377
abci5961 0:ae6c6727b545 378
abci5961 0:ae6c6727b545 379
abci5961 0:ae6c6727b545 380
abci5961 0:ae6c6727b545 381 /* Helper function for printing floats & doubles */
abci5961 0:ae6c6727b545 382 static char *print_double(char* str, double v, int decimalDigits=2)
abci5961 0:ae6c6727b545 383 {
abci5961 0:ae6c6727b545 384 int i = 1;
abci5961 0:ae6c6727b545 385 int intPart, fractPart;
abci5961 0:ae6c6727b545 386 int len;
abci5961 0:ae6c6727b545 387 char *ptr;
abci5961 0:ae6c6727b545 388
abci5961 0:ae6c6727b545 389 /* prepare decimal digits multiplicator */
abci5961 0:ae6c6727b545 390 for (;decimalDigits!=0; i*=10, decimalDigits--);
abci5961 0:ae6c6727b545 391
abci5961 0:ae6c6727b545 392 /* calculate integer & fractinal parts */
abci5961 0:ae6c6727b545 393 intPart = (int)v;
abci5961 0:ae6c6727b545 394 fractPart = (int)((v-(double)(int)v)*i);
abci5961 0:ae6c6727b545 395
abci5961 0:ae6c6727b545 396 /* fill in integer part */
abci5961 0:ae6c6727b545 397 sprintf(str, "%i.", intPart);
abci5961 0:ae6c6727b545 398
abci5961 0:ae6c6727b545 399 /* prepare fill in of fractional part */
abci5961 0:ae6c6727b545 400 len = strlen(str);
abci5961 0:ae6c6727b545 401 ptr = &str[len];
abci5961 0:ae6c6727b545 402
abci5961 0:ae6c6727b545 403 /* fill in leading fractional zeros */
abci5961 0:ae6c6727b545 404 for (i/=10;i>1; i/=10, ptr++) {
abci5961 0:ae6c6727b545 405 if (fractPart >= i) {
abci5961 0:ae6c6727b545 406 break;
abci5961 0:ae6c6727b545 407 }
abci5961 0:ae6c6727b545 408 *ptr = '0';
abci5961 0:ae6c6727b545 409 }
abci5961 0:ae6c6727b545 410
abci5961 0:ae6c6727b545 411 /* fill in (rest of) fractional part */
abci5961 0:ae6c6727b545 412 sprintf(ptr, "%i", fractPart);
abci5961 0:ae6c6727b545 413
abci5961 0:ae6c6727b545 414 return str;
abci5961 0:ae6c6727b545 415 }
abci5961 0:ae6c6727b545 416
abci5961 0:ae6c6727b545 417
abci5961 0:ae6c6727b545 418 //for testing sensor board ...
abci5961 0:ae6c6727b545 419 void test_sens(void)
abci5961 0:ae6c6727b545 420 {
abci5961 0:ae6c6727b545 421 while(1)
abci5961 0:ae6c6727b545 422 {
abci5961 0:ae6c6727b545 423
abci5961 0:ae6c6727b545 424 float value1, value2;
abci5961 0:ae6c6727b545 425 char buffer1[32], buffer2[32];
abci5961 0:ae6c6727b545 426 printf("\r\n");
abci5961 0:ae6c6727b545 427
abci5961 0:ae6c6727b545 428 hum_temp->get_temperature(&value1);
abci5961 0:ae6c6727b545 429 hum_temp->get_humidity(&value2);
abci5961 0:ae6c6727b545 430 printf("HTS221: [temp] %7s C, [hum] %s%%\r\n", print_double(buffer1, value1), print_double(buffer2, value2));
abci5961 0:ae6c6727b545 431
abci5961 0:ae6c6727b545 432 press_temp->get_temperature(&value1);
abci5961 0:ae6c6727b545 433 press_temp->get_pressure(&value2);
abci5961 0:ae6c6727b545 434 printf("LPS22HB: [temp] %7s C, [press] %s mbar\r\n", print_double(buffer1, value1), print_double(buffer2, value2));
abci5961 0:ae6c6727b545 435
abci5961 0:ae6c6727b545 436 wait(2);
abci5961 0:ae6c6727b545 437
abci5961 0:ae6c6727b545 438 }
abci5961 0:ae6c6727b545 439 }
abci5961 0:ae6c6727b545 440