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 Dec 21 19:19:19 2018 +0100
Revision:
3:37ebef02b334
Parent:
2:b72797c38464
Child:
4:43647366c69e
added greenPAK for revision D

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