Example of AWS IoT connection and Web Dashboard thru STM32 Nucleo evaluation board and mbed OS.
Dependencies: X_NUCLEO_IKS01A1 mbed FP MQTTPacket DnsQuery ATParser
Introduction
The demo is aimed to STM32 Nucleo board with WiFi and sensors expansions. The board is a "thing" for the AWS IoT service. It updates IoT service shadow with sensors data every second and checks subscription messages.
Hardware Configuration
- NUCLEO-F401RE - Nucleo Development Board
- X-NUCLEO-IDW01M1 - Wi-Fi expansion board for STM32 Nucleo
- X-NUCLEO-IKS01A1 - Motion MEMS and environmental sensor expansion board for STM32 Nucleo
Software Configuration
- Import this Project to mbed online compiler
- Find the next part of code in main.cpp file ...
WiFi network credential
#include "mbed.h" // WiFi network credential #define SSID "" // Network must be visible otherwise it can't connect #define PASSW "" #error "Wifi SSID & password empty"
- ... And set it to your Network Name and Password. Do not forget to remove "#error" pragma line.
Information
Nucleo WiFi module is not the same as your smartphone or laptope - it is based on demo board. To avoid connection problems:
- Place Nucleo as close to WiFi hot spot as possible. Or...
- Turn on mobile hot spot in your laptop as close to the device as possible.
- Make sure that hot spot permits 2.4 GHz band communications
- Setup BackEnd and store certificates using this backend setup instruction
- Find AWS_IOT_MQTT_HOST define and change it to HTTPS point mentioned in your AWS IoT thing properties named "interact"
#define AWS_IOT_MQTT_HOST "xxxxxxxxxx.iot.us-east-1.amazonaws.com" //Use your own host.
- Find the certificate defines clientCRT and clientKey in main.cpp file and change it to ones provided by Amazon.
/********************************************************************************************** *********************************************************************************************** Device Identity Certificates: Modify for your AWS IoT Thing *********************************************************************************************** ***********************************************************************************************/ /**************************************** (somecode)-certificate.pem.crt - Amazon signed PEM sertificate. *****************************************/ //This Client cert is example. Use own instead. const uint8_t clientCRT[] = "\ -----BEGIN CERTIFICATE-----\n\ MIIDBjCCAe6gAwIBAgIUVph856omeIxW3UPioq+UrX1DbwowDQYJKoZIhvcNAQEL\ BQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g\ SW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTE3MDUyNTExNTEy\ OVoXDTQ5MTIzMTIzNTk1OVowgZUxCzAJBgNVBAYTAkJZMQ4wDAYDVQQIDAVNaW5z\ azEOMAwGA1UEBwwFTWluc2sxFzAVBgNVBAoMDktsaWthLVRlY2ggTExDMRcwFQYD\ VQQLDA5LbGlrYS1UZWNoIExMQzEMMAoGA1UEAwwDUm5EMSYwJAYJKoZIhvcNAQkB\ FhdtdmF0YWxldUBrbGlrYS10ZWNoLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH\ A0IABCJgOQJmoTBJVPfli9Hm/JVixaxkY5rtlgrYO3hSl633A2hg0P/ue0wXDbF3\ aQ0X57IRFE4k4FEbr3UXjT/IczKjYDBeMB8GA1UdIwQYMBaAFK3YzTUPlYB2Li75\ i/z8rEogr1d6MB0GA1UdDgQWBBT18HXBaXFJuAR/0SwegnxJ+pyJ6TAMBgNVHRMB\ Af8EAjAAMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAb0Ux1aH5\ RLxjrfGqXN6rPVqh8QQRS+AyBfzmaQN8HaPZMkX5WxXLvcn0A3uWlwQxPPkcZ4zf\ 51GHtFFQWB4YZ8dx8mUQ0v/j7onHjCJgZ8iDgwOyKMGtnsDZWCakQw+a6cj+NrMZ\ tzhjwCzEEP6ePcbXwErI5OOzLuWns2L/JEr2wWNkokgRuS8ewr/SQ9OLWIWa2rFM\ ahPNTb3y/qBeWdjeJmhI+TOxdqIpsF8roWP25zwo/zkzCHCjXFBrL+0CA4MpxIl9\ x02i7aAhlJ6ys80lDxdeWeeQJXRKkGknP8mcmKn3iEqqJ5s1dQePj2b5d3ldatya\ wsxQBqqZXzIWEw==\ \n\ -----END CERTIFICATE-----\n"; /********************************************************************************************** *********************************************************************************************** Private Key: Modify for your AWS IoT Thing *********************************************************************************************** ***********************************************************************************************/ /********************************************************************8**************************************** nucleo.key.pem - client key generated according to readme. **************************************************************************************************************/ //This Client Key is example. Use own instead. const uint8_t clientKey[] ="\ -----BEGIN EC PARAMETERS-----\n\ BggqhkjOPQMBBw==\ -----END EC PARAMETERS-----\n\ -----BEGIN EC PRIVATE KEY-----\n\ MHcCAQEEIHPRfWSC8/k/BsqDWKuP15dXsI9fGwpkTIsLZe6mIrAAoAoGCCqGSM49\ AwEHoUQDQgAEImA5AmahMElU9+WL0eb8lWLFrGRjmu2WCtg7eFKXrfcDaGDQ/+57\ TBcNsXdpDRfnshEUTiTgURuvdReNP8hzMg==\ -----END EC PRIVATE KEY-----\n";
Build and Check
- Plugin your board to USB of your PC. USB Disk Drive and USB COM Port should appear in your system.
- Open any Serial Console, connect it to your USB Serial Port and setup speed equal to 115200.
- Compile this Project and save .bin file to USB Disk Drive
- After board reset you should see next log in serial console:
X-NUCLEO-IDW01M1 mbed Application connecting to AP LOG: int main() L#361 Connected to WiFI. LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#186 ===================================== LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#187 Connecting WiFi. LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#188 Nucleo IP ADDRESS: X.X.X.X LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#189 Nucleo MAC ADDRESS: 00:11:22:33:44:55 LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#190 Server Hostname: xxxxxxxx.iot.us-east-1.amazonaws.com port: 8883 LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#191 Client ID: Nucleo LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#194 ===================================== LOG: int MQTTSocket::getNTPtime(int) L#58 Success receiving time from ntp server. Tick from 1 Jan 1970 is equal to 1505399292. --->TCP Connected --->MQTT Connected --->>>MQTT subscribed to: Nucleo/test Length - 245, Publishing {"state": {"reported": {"temperature": 23.690001, "humidity": 98.190002, "pressure": 982.869141, "accelerometer": [-0.009000, 0.030000, 0.971000], "gyroscope": [0.420000, -2.660000, 1.750000], "magnetometer": [-3.600000, -7.100000, 53.300000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.660000, "humidity": 98.010002, "pressure": 982.770264, "accelerometer": [-0.009000, 0.030000, 0.971000], "gyroscope": [0.770000, -2.310000, 1.470000], "magnetometer": [-3.100000, -8.300000, 54.200000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.670000, "humidity": 98.129997, "pressure": 982.724121, "accelerometer": [-0.008000, 0.029000, 0.971000], "gyroscope": [0.630000, -2.380000, 1.400000], "magnetometer": [-3.100000, -7.900000, 53.400000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.690001, "humidity": 98.019997, "pressure": 982.840088, "accelerometer": [-0.009000, 0.030000, 0.972000], "gyroscope": [0.700000, -2.450000, 1.540000], "magnetometer": [-3.700000, -7.900000, 53.400000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.709999, "humidity": 98.040001, "pressure": 982.828613, "accelerometer": [-0.009000, 0.030000, 0.971000], "gyroscope": [0.630000, -2.520000, 1.470000], "magnetometer": [-2.900000, -7.400000, 52.400000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.719999, "humidity": 97.860001, "pressure": 982.917236, "accelerometer": [-0.026000, 0.103000, 0.891000], "gyroscope": [1.050000, -2.310000, 1.260000], "magnetometer": [-3.300000, -7.100000, 53.500000]}}}
Information
Device connection state might be checked by Green Led on the board. Green light means that device is connected and transferring data to cloud.
- Configure and start your dashboard using instruction and corresponding sources from github
- Use Blue button to set up markers to charts.
- Use AWS IoT console MQTT Client to test device subscription to "Nucleo/test". Just publish any message to this topic and serial port output.
- PROFIT!
Diff: main.cpp
- Revision:
- 0:4cdaf9b1e7d0
- Child:
- 1:042ca9148926
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Sep 27 14:40:52 2017 +0300 @@ -0,0 +1,399 @@ +/* SpwfInterface NetworkSocketAPI Example Program + * Copyright (c) 2015 ARM Limited + * Copyright (c) 2017 KLIKA TECH, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + Contributors: + * Klika Tech - completely adopted to Amazon AWS IoT service + + */ + +#include "mbed.h" +#include "SpwfInterface.h" +#include "TCPSocket.h" +#include "MQTTClient.h" +#include "MQTTWiFi.h" +#include <ctype.h> +#include "x_nucleo_iks01a1.h" + +//------------------------------------ +// Hyperterminal default configuration +// 9600 bauds, 8-bit data, no parity +//------------------------------------ +Serial pc(SERIAL_TX, SERIAL_RX); +DigitalOut myled(LED2); +DigitalOut butled(LED3); +InterruptIn mybutton(USER_BUTTON); + +bool myButtonPressed = false; + +#define MQTT_MAX_PACKET_SIZE 350 +#define MQTT_MAX_PAYLOAD_SIZE 300 + +#define AWS_IOT_MQTT_HOST "xxxxxxxxxx.iot.us-east-1.amazonaws.com" //Use your own host. +#define AWS_IOT_MQTT_PORT 8883 +#define AWS_IOT_MQTT_CLIENT_ID "Nucleo" //Should be kept if you are using same device clent. +#define AWS_IOT_MY_THING_NAME "Nucleo" //Should be kept if you are using same device thing name. +#define AWS_IOT_MQTT_TOPIC_TEST "Nucleo/test" +#define AWS_IOT_MQTT_TOPIC_DATA "Nucleo/data" +#define AWS_IOT_MQTT_TOPIC_SHADOW "$aws/things/Nucleo/shadow/update" +#define AWS_IOT_ID "" +#define AWS_IOT_AUTH_TOKEN "" + +// WiFi network credential +#define SSID "" // Network must be visible otherwise it can't connect +#define PASSW "" +#error "Wifi SSID & password empty" + +#include "stdint.h" + + +/********************************************************************************************** +*********************************************************************************************** + Root CA certificate: Never modify +*********************************************************************************************** +***********************************************************************************************/ + +//This root CA can be used. +const uint8_t rootCA[] = "\ +-----BEGIN CERTIFICATE-----\n\ +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB\ +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL\ +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp\ +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW\ +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0\ +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL\ +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW\ +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln\ +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp\ +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y\ +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1\ +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex\ +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz\ +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG\ +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+\ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/\ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E\ +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH\ +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy\ +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv\ +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE\ +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y\ +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK\ +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ\ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N\ +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao8WNq\n\ +-----END CERTIFICATE-----\n"; + +/********************************************************************************************** +*********************************************************************************************** + Device Identity Certificates: Modify for your AWS IoT Thing +*********************************************************************************************** +***********************************************************************************************/ + +/**************************************** +(somecode)-certificate.pem.crt - Amazon signed PEM sertificate. +*****************************************/ + +//This Client cert is example. Use own instead. +const uint8_t clientCRT[] = "\ +-----BEGIN CERTIFICATE-----\n\ +MIIDBjCCAe6gAwIBAgIUVph856omeIxW3UPioq+UrX1DbwowDQYJKoZIhvcNAQEL\ +BQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g\ +SW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTE3MDUyNTExNTEy\ +OVoXDEQ5MTIzMEIzNTk1OVowgZUxCzAJBgNVBAETAkJZMQ4wDAYDVQQIDAVNaW5z\ +azEOMAwGA1UEBwwFTWluc2sxFzAVBgNVBAoMDktsaWthLVRlY2ggTExDMRcwFQYD\ +VQQLDA5LbGlrYS1UZWNoIExMQzEMMAoGA1UEAwwDUm5EMSYwJAYJKoZIhvcNAQkB\ +FhdtdmF0YExldUBrbGlrYS10ZWNoLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH\ +A0IABCJgOQJmoTBJVPfEi9Hm/JVixaxkY5rtlgrYO3hSl633A2hg0P/ue0wXDbF3\ +aQ0X57IRFE4k4FEbr3UXjT/IczKjYDBeMB8GA1UdIwQYMBaAFK3YzTUPlYB2Li75\ +i/z8rEogr1d6MB0GA1UdDgQWBBT18HXBaXFJuER/0SwegnxJ+pyJ6TAMBgNVHRMB\ +Af8EAjAAMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAb0Ux1aH5\ +RLxjrfGqXN6rPVqh8QQRS+AyBfzmaQN8HaPZMkX5WxXLvcn0A3uWlwQxPPkcZ4zf\ +51GHtFFQWB4YZ8dx8mUQ0v/j7onHjCJgZ8iDgwOyKMGtnsDEWCakQw+a6cj+NrMZ\ +tzhjwCzEEP6EPcbXwErI5OOzLuWns2L/JEr2wWNkokgRuS8ewr/SQ9OLWIWa2rFM\ +ahPNTb3y/qBeWdjeJmhI+TOxdqIpsF8roWP25zwo/zkzCHCjXFBrL+0CA4MpxIl9\ +x02i7aAhlJ6ys80lDxdeWeeQJXRKkGknP8mcmKn3iEqqJ5s1dQePj2b5d3ldatya\ +wsxQBqqZXzIWEw==\ +\n\ +-----END CERTIFICATE-----\n"; + + + +/********************************************************************************************** +*********************************************************************************************** + Private Key: Modify for your AWS IoT Thing +*********************************************************************************************** +***********************************************************************************************/ + +/********************************************************************8**************************************** +nucleo.key.pem - client key generated according to readme. +**************************************************************************************************************/ + +//This Client Key is example. Use own instead. +const uint8_t clientKey[] ="\ +-----BEGIN EC PARAMETERS-----\n\ +BggqhEEOPQMBEw==\ +-----END EC PARAMETERS-----\n\ +-----BEGIN EC PRIVATE KEY-----\n\ +MHcCAQEEIHPRfWSC8/k/BsqDWKuP15dXsI9fGwpkTIsLZe6mIrAEoAoGCCqGSM49\ +AwEHoUQDQEAEImAEAEahMElU9+WL0eb8lWLFrGRjmu2WCtg7eFKXrfcDaGDQ/+57\ +TBcNsXdpDRfnshEETiTgURuvdReNP8hEMg==\ +-----END EC PRIVATE KEY-----\n"; + +int connack_rc = 0; // MQTT connack return code +int connectTimeout = 1000; +int retryAttempt = 0; + +PressureSensor *pressure_sensor; +HumiditySensor *humidity_sensor; +TempSensor *temp_sensor1; +MagneticSensor *magnetic_sensor; +GyroSensor *gyro_sensor; +MotionSensor *accel_sensor; + +MQTT::Message message; +MQTTString TopicName= { AWS_IOT_MQTT_TOPIC_TEST }; +MQTT::MessageData MsgData(TopicName, message); + +void subscribe_cb(MQTT::MessageData & msgMQTT) { + char msg[MQTT_MAX_PAYLOAD_SIZE]; + msg[0]='\0'; + strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen); + printf ("--->>> subscribe_cb msg: %s\n\r", msg); +} + +int subscribe(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) +{ + char* pubTopic = AWS_IOT_MQTT_TOPIC_TEST; + return client->subscribe(pubTopic, MQTT::QOS0, subscribe_cb); +} + +int connect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) +{ + SpwfSAInterface& WiFi = ipstack->getWiFi(); + + // Network debug statements + LOG("=====================================\n\r"); + LOG("Connecting WiFi.\n\r"); + LOG("Nucleo IP ADDRESS: %s\n\r", WiFi.get_ip_address()); + LOG("Nucleo MAC ADDRESS: %s\n\r", WiFi.get_mac_address()); + LOG("Server Hostname: %s port: %d\n\r", AWS_IOT_MQTT_HOST, AWS_IOT_MQTT_PORT); + LOG("Client ID: %s\n\r", AWS_IOT_MQTT_CLIENT_ID); + //LOG("Topic: %s\n\r", AWS_IOT_MQTT_TOPIC_TEST); + //LOG("Subscription URL: %s\n\r", subscription_url); + LOG("=====================================\n\r"); + + ipstack->open(&ipstack->getWiFi()); + + int rc=ipstack->getNTPtime(); + + if (rc != 0) + { + ERROR("Get NTP time error: %d\n", rc); + return rc; + } + + rc = WiFi.setSocketClientSecurity((uint8_t *)"m", (uint8_t *)rootCA, (uint8_t *)clientCRT, (uint8_t *)clientKey, (uint8_t *)AWS_IOT_MQTT_HOST, ipstack->getTime()); + + if (rc != 0) + { + ERROR("Set security params error: %d\n", rc); + return rc; + } + + rc = ipstack->connect(AWS_IOT_MQTT_HOST, AWS_IOT_MQTT_PORT, connectTimeout); + + if (rc != 0) + { + WARN("IP Stack connect returned: %d\n", rc); + return rc; + } + + printf ("--->TCP Connected\n\r"); + + // MQTT Connect + MQTTPacket_connectData data = MQTTPacket_connectData_initializer; + data.MQTTVersion = 4; + data.struct_version=0; + data.clientID.cstring = AWS_IOT_MQTT_CLIENT_ID; + //data.username.cstring = "use-token-auth"; + //data.password.cstring = AWS_IOT_AUTH_TOKEN; + + if ((rc = client->connect(data)) == 0) + { + printf ("--->MQTT Connected\n\r"); + + if (!subscribe(client, ipstack)) printf ("--->>>MQTT subscribed to: %s\n\r",AWS_IOT_MQTT_TOPIC_TEST); + } + else + { + WARN("MQTT connect returned %d\n", rc); + } + if (rc >= 0) + connack_rc = rc; + return rc; +} + +int getConnTimeout(int attemptNumber) +{ // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute + // after 20 attempts, retry every 10 minutes + return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; +} + +void attemptConnect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) +{ + while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED) + { + if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) + { + printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc); + return; // don't reattempt to connect if credentials are wrong + } + + int timeout = getConnTimeout(++retryAttempt); + WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); + + // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed + // or maybe just add the proper members to do this disconnect and call attemptConnect(...) + // this works - reset the system when the retry count gets to a threshold + if (retryAttempt == 5) + { + ipstack->getWiFi().reset_chip(); + NVIC_SystemReset(); + } + else + wait(timeout); + } +} + +int publish(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) +{ + MQTT::Message message; + char* pubTopic = AWS_IOT_MQTT_TOPIC_SHADOW; + + char buf[MQTT_MAX_PAYLOAD_SIZE]; + float temp, press, hum; + int32_t magnet[3]; + int32_t gyro[3]; + int32_t accel[3]; + + temp_sensor1->GetTemperature(&temp); + pressure_sensor->GetPressure(&press); + humidity_sensor->GetHumidity(&hum); + magnetic_sensor->Get_M_Axes(magnet); + gyro_sensor->Get_G_Axes(gyro); + accel_sensor->Get_X_Axes(accel); + + /*sprintf(buf, + "{\"d\":{\"ST\":\"Nucleo-IoT-mbed\",\"Temp\":%0.4f,\"Pressure\":%0.4f,\"Humidity\":%0.4f}}", + temp, press, hum);*/ + + if (!myButtonPressed) + { + butled = 1; + sprintf(buf, "{\"state\": {\"reported\": {\"temperature\": %f, \"humidity\": %f, \"pressure\": %f, \"accelerometer\": [%f, %f, %f], \"gyroscope\": [%f, %f, %f], \"magnetometer\": [%f, %f, %f]}}}", + temp, hum, press, accel[0]/1000.0, accel[1]/1000.0, accel[2]/1000.0, gyro[0]/1000.0, gyro[1]/1000.0, gyro[2]/1000.0, magnet[0]/10.0, magnet[1]/10.0, magnet[2]/10.0); + } + else + { + myButtonPressed = false; // reset state + butled = 0; + + sprintf(buf, "{\"temperature\": %f, \"humidity\": %f, \"pressure\": %f, \"accelerometer\": [%f, %f, %f], \"gyroscope\": [%f, %f, %f], \"magnetometer\": [%f, %f, %f], \"marker\": true}", + temp, hum, press, accel[0]/1000.0, accel[1]/1000.0, accel[2]/1000.0, gyro[0]/1000.0, gyro[1]/1000.0, gyro[2]/1000.0, magnet[0]/10.0, magnet[1]/10.0, magnet[2]/10.0); + pubTopic = AWS_IOT_MQTT_TOPIC_DATA; + } + + message.qos = MQTT::QOS0; + message.retained = false; + message.dup = false; + message.payload = (void*)buf; + message.payloadlen = strlen(buf); + + printf("Length - %d, Publishing %s\n\r", strlen(buf), buf); + + return client->publish(pubTopic, message); +} + +void pressed() +{ + myButtonPressed = true; +} + +int main() +{ + const char * ssid = SSID; // Network must be visible otherwise it can't connect + const char * seckey = PASSW; + + pc.baud(115200); + + SpwfSAInterface spwf(D8, D2, false); + + myled=0; + DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL); + i2c->frequency(400000); + + mybutton.fall(&pressed); + + X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(i2c); + pressure_sensor = mems_expansion_board->pt_sensor; + temp_sensor1 = mems_expansion_board->ht_sensor; + humidity_sensor = mems_expansion_board->ht_sensor; + magnetic_sensor = mems_expansion_board->magnetometer; + gyro_sensor = mems_expansion_board->GetGyroscope(); + accel_sensor = mems_expansion_board->GetAccelerometer(); + + pc.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n"); + pc.printf("\r\nconnecting to AP\r\n"); + + MQTTWiFi ipstack(spwf, ssid, seckey, NSAPI_SECURITY_WPA2); + + LOG("Connected to WiFI.\r\n"); + + MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); + + attemptConnect(&client, &ipstack); + + if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) + { + while (true) + wait(1.0); // Permanent failures - don't retry + } + + myled=1; + + int count = 0; + + while (true) + { + if (++count == 100) + { + myled = 0; + // Publish a message every second + if (publish(&client, &ipstack) != 0) + { + myled=0; + ipstack.getWiFi().reset_chip(); + NVIC_SystemReset(); + attemptConnect(&client, &ipstack); // if we have lost the connection + } + else myled=1; + + count = 0; + } + + client.yield(10); // allow the MQTT client to receive messages + } +}