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

https://github.com/Klika-Tech/nucleo-aws-iot-demo/raw/master/doc/assets/device.jpg

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:

  1. Place Nucleo as close to WiFi hot spot as possible. Or...
  2. Turn on mobile hot spot in your laptop as close to the device as possible.
  3. 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

  1. Plugin your board to USB of your PC. USB Disk Drive and USB COM Port should appear in your system.
  2. Open any Serial Console, connect it to your USB Serial Port and setup speed equal to 115200.
  3. Compile this Project and save .bin file to USB Disk Drive
  4. 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.

  1. Configure and start your dashboard using instruction and corresponding sources from github
  2. Use Blue button to set up markers to charts.
  3. Use AWS IoT console MQTT Client to test device subscription to "Nucleo/test". Just publish any message to this topic and serial port output.
  4. PROFIT!
Committer:
PavelSavyhin
Date:
Thu Oct 19 11:36:41 2017 +0000
Revision:
1:042ca9148926
Parent:
0:4cdaf9b1e7d0
Connection times are optimized and logging is extended.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
PavelSavyhin 0:4cdaf9b1e7d0 1 /* SocketAddress
PavelSavyhin 0:4cdaf9b1e7d0 2 * Copyright (c) 2015 ARM Limited
PavelSavyhin 0:4cdaf9b1e7d0 3 *
PavelSavyhin 0:4cdaf9b1e7d0 4 * Licensed under the Apache License, Version 2.0 (the "License");
PavelSavyhin 0:4cdaf9b1e7d0 5 * you may not use this file except in compliance with the License.
PavelSavyhin 0:4cdaf9b1e7d0 6 * You may obtain a copy of the License at
PavelSavyhin 0:4cdaf9b1e7d0 7 *
PavelSavyhin 0:4cdaf9b1e7d0 8 * http://www.apache.org/licenses/LICENSE-2.0
PavelSavyhin 0:4cdaf9b1e7d0 9 *
PavelSavyhin 0:4cdaf9b1e7d0 10 * Unless required by applicable law or agreed to in writing, software
PavelSavyhin 0:4cdaf9b1e7d0 11 * distributed under the License is distributed on an "AS IS" BASIS,
PavelSavyhin 0:4cdaf9b1e7d0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
PavelSavyhin 0:4cdaf9b1e7d0 13 * See the License for the specific language governing permissions and
PavelSavyhin 0:4cdaf9b1e7d0 14 * limitations under the License.
PavelSavyhin 0:4cdaf9b1e7d0 15 */
PavelSavyhin 0:4cdaf9b1e7d0 16
PavelSavyhin 0:4cdaf9b1e7d0 17 #ifndef SOCKET_ADDRESS_H
PavelSavyhin 0:4cdaf9b1e7d0 18 #define SOCKET_ADDRESS_H
PavelSavyhin 0:4cdaf9b1e7d0 19
PavelSavyhin 0:4cdaf9b1e7d0 20 #include <stdint.h>
PavelSavyhin 0:4cdaf9b1e7d0 21
PavelSavyhin 0:4cdaf9b1e7d0 22
PavelSavyhin 0:4cdaf9b1e7d0 23 /** Maximum size of IP address representation
PavelSavyhin 0:4cdaf9b1e7d0 24 */
PavelSavyhin 0:4cdaf9b1e7d0 25 #define NSAPI_IP_SIZE NSAPI_IPv6_SIZE
PavelSavyhin 0:4cdaf9b1e7d0 26
PavelSavyhin 0:4cdaf9b1e7d0 27 /** Maximum number of bytes for IP address
PavelSavyhin 0:4cdaf9b1e7d0 28 */
PavelSavyhin 0:4cdaf9b1e7d0 29 #define NSAPI_IP_BYTES NSAPI_IPv6_BYTES
PavelSavyhin 0:4cdaf9b1e7d0 30
PavelSavyhin 0:4cdaf9b1e7d0 31 /** Maximum size of MAC address representation
PavelSavyhin 0:4cdaf9b1e7d0 32 */
PavelSavyhin 0:4cdaf9b1e7d0 33 #define NSAPI_MAC_SIZE 18
PavelSavyhin 0:4cdaf9b1e7d0 34
PavelSavyhin 0:4cdaf9b1e7d0 35 /** Maximum number of bytes for MAC address
PavelSavyhin 0:4cdaf9b1e7d0 36 */
PavelSavyhin 0:4cdaf9b1e7d0 37 #define NSAPI_MAC_BYTES 6
PavelSavyhin 0:4cdaf9b1e7d0 38
PavelSavyhin 0:4cdaf9b1e7d0 39 /** Enum of IP address versions
PavelSavyhin 0:4cdaf9b1e7d0 40 *
PavelSavyhin 0:4cdaf9b1e7d0 41 * The IP version specifies the type of an IP address.
PavelSavyhin 0:4cdaf9b1e7d0 42 *
PavelSavyhin 0:4cdaf9b1e7d0 43 * @enum nsapi_version_t
PavelSavyhin 0:4cdaf9b1e7d0 44 */
PavelSavyhin 0:4cdaf9b1e7d0 45 enum nsapi_version_t {
PavelSavyhin 0:4cdaf9b1e7d0 46 NSAPI_IPv4, /*!< Address is IPv4 */
PavelSavyhin 0:4cdaf9b1e7d0 47 NSAPI_IPv6, /*!< Address is IPv6 */
PavelSavyhin 0:4cdaf9b1e7d0 48 };
PavelSavyhin 0:4cdaf9b1e7d0 49
PavelSavyhin 0:4cdaf9b1e7d0 50 /** Size of IPv4 representation
PavelSavyhin 0:4cdaf9b1e7d0 51 */
PavelSavyhin 0:4cdaf9b1e7d0 52 #define NSAPI_IPv4_SIZE 16
PavelSavyhin 0:4cdaf9b1e7d0 53
PavelSavyhin 0:4cdaf9b1e7d0 54 /** Number of bytes in IPv4 address
PavelSavyhin 0:4cdaf9b1e7d0 55 */
PavelSavyhin 0:4cdaf9b1e7d0 56 #define NSAPI_IPv4_BYTES 4
PavelSavyhin 0:4cdaf9b1e7d0 57
PavelSavyhin 0:4cdaf9b1e7d0 58 /** Size of IPv6 representation
PavelSavyhin 0:4cdaf9b1e7d0 59 */
PavelSavyhin 0:4cdaf9b1e7d0 60 #define NSAPI_IPv6_SIZE 40
PavelSavyhin 0:4cdaf9b1e7d0 61
PavelSavyhin 0:4cdaf9b1e7d0 62 /** Number of bytes in IPv6 address
PavelSavyhin 0:4cdaf9b1e7d0 63 */
PavelSavyhin 0:4cdaf9b1e7d0 64 #define NSAPI_IPv6_BYTES 16
PavelSavyhin 0:4cdaf9b1e7d0 65
PavelSavyhin 0:4cdaf9b1e7d0 66 // Predeclared classes
PavelSavyhin 0:4cdaf9b1e7d0 67 class NetworkStack;
PavelSavyhin 0:4cdaf9b1e7d0 68
PavelSavyhin 0:4cdaf9b1e7d0 69
PavelSavyhin 0:4cdaf9b1e7d0 70 /** SocketAddress class
PavelSavyhin 0:4cdaf9b1e7d0 71 *
PavelSavyhin 0:4cdaf9b1e7d0 72 * Representation of an IP address and port pair.
PavelSavyhin 0:4cdaf9b1e7d0 73 */
PavelSavyhin 0:4cdaf9b1e7d0 74 class SocketAddress {
PavelSavyhin 0:4cdaf9b1e7d0 75 public:
PavelSavyhin 0:4cdaf9b1e7d0 76 /** Create a SocketAddress from a hostname and port
PavelSavyhin 0:4cdaf9b1e7d0 77 *
PavelSavyhin 0:4cdaf9b1e7d0 78 * The hostname may be either a domain name or an IP address. If the
PavelSavyhin 0:4cdaf9b1e7d0 79 * hostname is an IP address, no network transactions will be performed.
PavelSavyhin 0:4cdaf9b1e7d0 80 *
PavelSavyhin 0:4cdaf9b1e7d0 81 * On failure, the IP address and port will be set to zero
PavelSavyhin 0:4cdaf9b1e7d0 82 *
PavelSavyhin 0:4cdaf9b1e7d0 83 * @param iface Network stack to use for DNS resolution
PavelSavyhin 0:4cdaf9b1e7d0 84 * @param host Hostname to resolve
PavelSavyhin 0:4cdaf9b1e7d0 85 * @param port Optional 16-bit port
PavelSavyhin 0:4cdaf9b1e7d0 86 */
PavelSavyhin 0:4cdaf9b1e7d0 87 SocketAddress(NetworkStack *iface, const char *host, uint16_t port = 0);
PavelSavyhin 0:4cdaf9b1e7d0 88
PavelSavyhin 0:4cdaf9b1e7d0 89 /** Create a SocketAddress from an IP address and port
PavelSavyhin 0:4cdaf9b1e7d0 90 *
PavelSavyhin 0:4cdaf9b1e7d0 91 * @param host Null-terminated representation of the IP address
PavelSavyhin 0:4cdaf9b1e7d0 92 * @param port Optional 16-bit port
PavelSavyhin 0:4cdaf9b1e7d0 93 */
PavelSavyhin 0:4cdaf9b1e7d0 94 SocketAddress(const char *addr = 0, uint16_t port = 0);
PavelSavyhin 0:4cdaf9b1e7d0 95
PavelSavyhin 0:4cdaf9b1e7d0 96 /** Create a SocketAddress from a raw IP address and port
PavelSavyhin 0:4cdaf9b1e7d0 97 *
PavelSavyhin 0:4cdaf9b1e7d0 98 * @param bytes Raw IP address in big-endian order
PavelSavyhin 0:4cdaf9b1e7d0 99 * @param version IP address version, NSAPI_IPv4 or NSAPI_IPv6
PavelSavyhin 0:4cdaf9b1e7d0 100 * @param port Optional 16-bit port
PavelSavyhin 0:4cdaf9b1e7d0 101 */
PavelSavyhin 0:4cdaf9b1e7d0 102 SocketAddress(const void *bytes, nsapi_version_t version, uint16_t port = 0);
PavelSavyhin 0:4cdaf9b1e7d0 103
PavelSavyhin 0:4cdaf9b1e7d0 104 /** Create a SocketAddress from another SocketAddress
PavelSavyhin 0:4cdaf9b1e7d0 105 *
PavelSavyhin 0:4cdaf9b1e7d0 106 * @param address SocketAddress to copy
PavelSavyhin 0:4cdaf9b1e7d0 107 */
PavelSavyhin 0:4cdaf9b1e7d0 108 SocketAddress(const SocketAddress &addr);
PavelSavyhin 0:4cdaf9b1e7d0 109
PavelSavyhin 0:4cdaf9b1e7d0 110 /** Set the IP address
PavelSavyhin 0:4cdaf9b1e7d0 111 *
PavelSavyhin 0:4cdaf9b1e7d0 112 * @param addr Null-terminated represention of the IP address
PavelSavyhin 0:4cdaf9b1e7d0 113 */
PavelSavyhin 0:4cdaf9b1e7d0 114 void set_ip_address(const char *addr);
PavelSavyhin 0:4cdaf9b1e7d0 115
PavelSavyhin 0:4cdaf9b1e7d0 116 /** Set the raw IP address
PavelSavyhin 0:4cdaf9b1e7d0 117 *
PavelSavyhin 0:4cdaf9b1e7d0 118 * @param bytes Raw IP address in big-endian order
PavelSavyhin 0:4cdaf9b1e7d0 119 * @param version IP address version, NSAPI_IPv4 or NSAPI_IPv6
PavelSavyhin 0:4cdaf9b1e7d0 120 */
PavelSavyhin 0:4cdaf9b1e7d0 121 void set_ip_bytes(const void *bytes, nsapi_version_t version);
PavelSavyhin 0:4cdaf9b1e7d0 122
PavelSavyhin 0:4cdaf9b1e7d0 123 /** Set the port
PavelSavyhin 0:4cdaf9b1e7d0 124 *
PavelSavyhin 0:4cdaf9b1e7d0 125 * @param port 16-bit port
PavelSavyhin 0:4cdaf9b1e7d0 126 */
PavelSavyhin 0:4cdaf9b1e7d0 127 void set_port(uint16_t port);
PavelSavyhin 0:4cdaf9b1e7d0 128
PavelSavyhin 0:4cdaf9b1e7d0 129 /** Get the IP address
PavelSavyhin 0:4cdaf9b1e7d0 130 *
PavelSavyhin 0:4cdaf9b1e7d0 131 * @return Null-terminated representation of the IP Address
PavelSavyhin 0:4cdaf9b1e7d0 132 */
PavelSavyhin 0:4cdaf9b1e7d0 133 const char *get_ip_address() const;
PavelSavyhin 0:4cdaf9b1e7d0 134
PavelSavyhin 0:4cdaf9b1e7d0 135 /** Get the raw IP address
PavelSavyhin 0:4cdaf9b1e7d0 136 *
PavelSavyhin 0:4cdaf9b1e7d0 137 * @return Raw IP address in big-endian order
PavelSavyhin 0:4cdaf9b1e7d0 138 */
PavelSavyhin 0:4cdaf9b1e7d0 139 const void *get_ip_bytes() const;
PavelSavyhin 0:4cdaf9b1e7d0 140
PavelSavyhin 0:4cdaf9b1e7d0 141 /** Get the IP address version
PavelSavyhin 0:4cdaf9b1e7d0 142 *
PavelSavyhin 0:4cdaf9b1e7d0 143 * @return IP address version, NSAPI_IPv4 or NSAPI_IPv6
PavelSavyhin 0:4cdaf9b1e7d0 144 */
PavelSavyhin 0:4cdaf9b1e7d0 145 nsapi_version_t get_ip_version() const;
PavelSavyhin 0:4cdaf9b1e7d0 146
PavelSavyhin 0:4cdaf9b1e7d0 147 /** Get the port
PavelSavyhin 0:4cdaf9b1e7d0 148 *
PavelSavyhin 0:4cdaf9b1e7d0 149 * @return The 16-bit port
PavelSavyhin 0:4cdaf9b1e7d0 150 */
PavelSavyhin 0:4cdaf9b1e7d0 151 uint16_t get_port() const;
PavelSavyhin 0:4cdaf9b1e7d0 152
PavelSavyhin 0:4cdaf9b1e7d0 153 /** Test if address is zero
PavelSavyhin 0:4cdaf9b1e7d0 154 *
PavelSavyhin 0:4cdaf9b1e7d0 155 * @return True if address is not zero
PavelSavyhin 0:4cdaf9b1e7d0 156 */
PavelSavyhin 0:4cdaf9b1e7d0 157 operator bool() const;
PavelSavyhin 0:4cdaf9b1e7d0 158
PavelSavyhin 0:4cdaf9b1e7d0 159 private:
PavelSavyhin 0:4cdaf9b1e7d0 160 char _ip_address[NSAPI_IP_SIZE];
PavelSavyhin 0:4cdaf9b1e7d0 161 uint8_t _ip_bytes[NSAPI_IP_BYTES];
PavelSavyhin 0:4cdaf9b1e7d0 162 nsapi_version_t _ip_version;
PavelSavyhin 0:4cdaf9b1e7d0 163 uint16_t _port;
PavelSavyhin 0:4cdaf9b1e7d0 164 };
PavelSavyhin 0:4cdaf9b1e7d0 165
PavelSavyhin 0:4cdaf9b1e7d0 166 #endif