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!
Revision 1:042ca9148926, committed 2017-10-19
- Comitter:
- PavelSavyhin
- Date:
- Thu Oct 19 11:36:41 2017 +0000
- Parent:
- 0:4cdaf9b1e7d0
- Commit message:
- Connection times are optimized and logging is extended.
Changed in this revision
diff -r 4cdaf9b1e7d0 -r 042ca9148926 MQTT/MQTTSocket.h --- a/MQTT/MQTTSocket.h Wed Sep 27 14:40:52 2017 +0300 +++ b/MQTT/MQTTSocket.h Thu Oct 19 11:36:41 2017 +0000 @@ -23,6 +23,7 @@ int getNTPtime(int timeout=1000) { int err; + int attempts = 0; uint8_t timedata[4]; @@ -34,6 +35,9 @@ if (err != 0) { LOG("ERROR resolving ntp server IP and connecting to it! \r\n"); + attempts++; + if (attempts == 3) + return err; } } while (err != 0);
diff -r 4cdaf9b1e7d0 -r 042ca9148926 NetworkSocketAPI/NetworkStack.cpp --- a/NetworkSocketAPI/NetworkStack.cpp Wed Sep 27 14:40:52 2017 +0300 +++ b/NetworkSocketAPI/NetworkStack.cpp Thu Oct 19 11:36:41 2017 +0000 @@ -20,8 +20,14 @@ int NetworkStack::gethostbyname(SocketAddress *address, const char *name) { char buffer[NSAPI_IP_SIZE]; - int err = dnsQuery(this, name, buffer); - if (err) { + UDPSocket sock(this); + + sock.set_timeout(3000); + + int err = dnsQuery(&sock, name, buffer); + + if (err) + { return err; }
diff -r 4cdaf9b1e7d0 -r 042ca9148926 X_NUCLEO_IDW01M1v2/SPWF01SA/SPWFSA01.cpp --- a/X_NUCLEO_IDW01M1v2/SPWF01SA/SPWFSA01.cpp Wed Sep 27 14:40:52 2017 +0300 +++ b/X_NUCLEO_IDW01M1v2/SPWF01SA/SPWFSA01.cpp Thu Oct 19 11:36:41 2017 +0000 @@ -19,7 +19,7 @@ #include "stdint.h" #define SPWFSA01_CONNECT_TIMEOUT 15000 -#define SPWFSA01_SEND_TIMEOUT 500 +#define SPWFSA01_SEND_TIMEOUT 5000 #define SPWFSA01_RECV_TIMEOUT 1500//some commands like AT&F/W takes some time to get the result back! #define SPWFSA01_MISC_TIMEOUT 500 #define SPWFSA01_SOCKQ_TIMEOUT 3000
diff -r 4cdaf9b1e7d0 -r 042ca9148926 X_NUCLEO_IDW01M1v2/SPWF01SA/SPWFSA01.h --- a/X_NUCLEO_IDW01M1v2/SPWF01SA/SPWFSA01.h Wed Sep 27 14:40:52 2017 +0300 +++ b/X_NUCLEO_IDW01M1v2/SPWF01SA/SPWFSA01.h Thu Oct 19 11:36:41 2017 +0000 @@ -149,6 +149,9 @@ * Checks if data can be written */ bool writeable(); + + /** Sets debug mode */ + inline void set_debug(bool state) { dbg_on = state;_parser.debugOn(state);}; private: BufferedSerial _serial;
diff -r 4cdaf9b1e7d0 -r 042ca9148926 X_NUCLEO_IDW01M1v2/SpwfInterface.h --- a/X_NUCLEO_IDW01M1v2/SpwfInterface.h Wed Sep 27 14:40:52 2017 +0300 +++ b/X_NUCLEO_IDW01M1v2/SpwfInterface.h Thu Oct 19 11:36:41 2017 +0000 @@ -66,6 +66,7 @@ virtual const char *get_mac_address(); void debug(const char * string); inline bool reset_chip() {return _spwf.hw_reset();}; + inline void set_debug(bool state) {_spwf.set_debug(state); }; //Implementation of NetworkStack virtual const char *get_ip_address();
diff -r 4cdaf9b1e7d0 -r 042ca9148926 main.cpp --- a/main.cpp Wed Sep 27 14:40:52 2017 +0300 +++ b/main.cpp Thu Oct 19 11:36:41 2017 +0000 @@ -41,7 +41,7 @@ #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_HOST "a3t8vwpkw3sltg.iot.us-east-2.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. @@ -109,23 +109,22 @@ //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==\ +MIIC8jCCAdqgAwIBAgIVAJrIfpHLnCshC2j/Tp0dBJlSgaFnMA0GCSqGSIb3DQEB\ +CwUAME0xSzBJBgNVBAsMQkFtYXpvbiBXZWIgU2VydmljZXMgTz1BbWF6b24uY29t\ +IEluYy4gTD1TZWF0dGxlIFNUPVdhc2hpbmd0b24gQz1VUzAeFw0xNzA5MTUxMjQ3\ +NDBaFw00OTEyMzEyMzU5NTlaMIGAMQswCQYDVQQGEwJERTENMAsGA1UECBMERGVt\ +bzENMAsGA1UEBxMERGVtbzENMAsGA1UEChMERGVtbzENMAsGA1UECxMERGVtbzEN\ +MAsGA1UEAxMERGVtbzEmMCQGCSqGSIb3DQEJARYXcHNhdnloaW5Aa2xpa2EtdGVj\ +aC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT5IihA21BQZFW0vSdVxNuD\ +VKXAN7rI3Op3/MiWOlXqHEGHZeYs5ug8qEYkDZDkafhO87LNC0xhNSnGsNnNmyPI\ +o2AwXjAfBgNVHSMEGDAWgBRF1n2grhwmYjwSZmF74bVqm/enfjAdBgNVHQ4EFgQU\ +qSNNYMI1XGRMnnLenZlU1h/WNAkwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMC\ +B4AwDQYJKoZIhvcNAQELBQADggEBADTAhidWjd+MD6sLqr8+ZTdIcka0kT0tnMGy\ +Chz5ixaDpNI/OS9fi+SfOAd1Dd+/panpNtvJ5OfN0wkYJRd+lhBaN8M5lWsIF7EM\ +FvFtc+UV2cvGyYmSW47fFaV3DOv8vL068cmpNkd/HF8q9r0QNd0h2o97G99Xkk9k\ +90DIOgzu0C3sSTy5xDankCvfWIM2ibh5Laz3NmIqVW9jnnkMpQ00xViR8IdnfR4g\ +ke1C33ZQh1yTGNEE94nVGRMB2cPY62ChrM/ffgmUo4De0M45tX8ucFVL+ZwaCc3E\ +pmjMxFza6yZU50a74zZESmWGR5HYp0PSovglr9Xc5jvktqSugKM=\ \n\ -----END CERTIFICATE-----\n"; @@ -144,12 +143,12 @@ //This Client Key is example. Use own instead. const uint8_t clientKey[] ="\ -----BEGIN EC PARAMETERS-----\n\ -BggqhEEOPQMBEw==\ +BggqhkjOPQMBBw==\ -----END EC PARAMETERS-----\n\ -----BEGIN EC PRIVATE KEY-----\n\ -MHcCAQEEIHPRfWSC8/k/BsqDWKuP15dXsI9fGwpkTIsLZe6mIrAEoAoGCCqGSM49\ -AwEHoUQDQEAEImAEAEahMElU9+WL0eb8lWLFrGRjmu2WCtg7eFKXrfcDaGDQ/+57\ -TBcNsXdpDRfnshEETiTgURuvdReNP8hEMg==\ +MHcCAQEEIByuPtqukIClJ35+FA0gdvlMs7FmSFiOJGpaYsyQs4wwoAoGCCqGSM49\ +AwEHoUQDQgAE+SIoQNtQUGRVtL0nVcTbg1SlwDe6yNzqd/zIljpV6hxBh2XmLObo\ +PKhGJA2Q5Gn4TvOyzQtMYTUpxrDZzZsjyA==\ -----END EC PRIVATE KEY-----\n"; int connack_rc = 0; // MQTT connack return code @@ -201,7 +200,7 @@ if (rc != 0) { - ERROR("Get NTP time error: %d\n", rc); + WARN("Get NTP time error: %d\n", rc); return rc; } @@ -209,7 +208,7 @@ if (rc != 0) { - ERROR("Set security params error: %d\n", rc); + WARN("Set security params error: %d\n", rc); return rc; } @@ -217,7 +216,7 @@ if (rc != 0) { - WARN("IP Stack connect returned: %d\n", rc); + WARN("IP Stack connect returned: %d\n\r", rc); return rc; } @@ -263,12 +262,12 @@ } int timeout = getConnTimeout(++retryAttempt); - WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); + WARN("Retry attempt number %d waiting %d\n\r", 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) + if (retryAttempt == 2) { ipstack->getWiFi().reset_chip(); NVIC_SystemReset(); @@ -295,11 +294,7 @@ 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; @@ -339,7 +334,7 @@ pc.baud(115200); - SpwfSAInterface spwf(D8, D2, false); + SpwfSAInterface spwf(D8, D2, true); myled=0; DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL); @@ -355,14 +350,23 @@ gyro_sensor = mems_expansion_board->GetGyroscope(); accel_sensor = mems_expansion_board->GetAccelerometer(); + // Due to bug in mbed this workaround is needed to avoid Nucleo hang up when lsm6ds3 is absent + if (mems_expansion_board->gyro_lsm6ds3 == NULL) + { + NVIC_DisableIRQ(EXTI4_IRQn); + NVIC_ClearPendingIRQ(EXTI4_IRQn); + } + 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"); + + spwf.set_debug(false); - MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); + MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack, 5000); attemptConnect(&client, &ipstack); @@ -378,7 +382,7 @@ while (true) { - if (++count == 100) + if (++count == 1) { myled = 0; // Publish a message every second @@ -394,6 +398,6 @@ count = 0; } - client.yield(10); // allow the MQTT client to receive messages + client.yield(1000); // allow the MQTT client to receive messages } }