Basics of Design Research & Design Hub

AWS for IoT Projects

Written by Dhairya A. Parikh

Getting Started

Amazon Web Services (AWS) IoT is one of the most popular Internet-of-Things (IoT) enterprise services. Today, thousands of companies around the world use it. But it’s not just for companies—AWS is accessible to everyone. In this article, I cover an IoT project that uses AWS as its primary IoT communication platform.

  • What is a simple project that uses AWS IoT?
  • How can I use a NodeMCU in an IoT project?
  • What project can I build with a DHT11 sensor?
  • NodeMCU
  • DHT11 sensor
  • AWS IoT

Needless to say, AWS is an industry leader in the cloud revolution. Among its suite of services, it has several designed specifically for enterprise Internet-of-Things (IoT) applications. But developers often don’t use these because connecting IoT devices to AWS can be somewhat complex. There are many questions, too, such as cost, and what developer devices are supported.

I’ll address these questions in this article, and outline a project wherein my NodeMCU development board sends temperature and humidity data to AWS IoT. For clarity, I’ve divided this piece into four parts:

  • Setting up your AWS Account
  • Project explanation and hardware setup
  • NodeMCU code explanation
  • Project demonstration and conclusion

So let’s get started by setting up our own AWS account.

SETTING UP YOUR FIRST AWS ACCOUNT

This article assumes that you have never used AWS for any of your projects and are exploring the platform for the first time. AWS provides a 12-month free subscription to new users. You can learn more at about this at Amazon’s AWS webpage, a link for which is available on Circuit Cellar‘s article materials page [1].

When you set up a new account for personal use, the platform activates the free tier by default. The aforementioned link provides free tier service descriptions. Click on the hard-to-miss “Create a Free Account” button (Figure 1), and provide the requested information.

Figure 1
The AWS free tier page (Source: Amazon AWS)
Figure 1
The AWS free tier page (Source: Amazon AWS)

Note: For the question, “How do you plan to use AWS?,” select “Personal—for your own projects.” Selecting “Business” may make you ineligible for the free tier option. Also note that you will be asked to enter your debit or credit card details. Don’t worry—this information’s only for verification purposes, and AWS will not charge you until the end of your free trial period, or if you use a service not covered under the trial.

Once this process is complete, go to the main Amazon AWS webpage to sign in with your new account credentials. Easy, right? In the next section, we will set up the AWS IoT Core service so that we can connect our NodeMCU device for data transmission and reception.

SETTING UP AWS IOT CORE

AWS IoT Core is the primary AWS service for connecting, testing and managing IoT devices through an interactive user interface that utilizes the security of AWS. In this section, we will set up an AWS IoT Core so that we can securely connect our NodeMCU device to this platform as an IoT client.

To connect an external microcontroller (MCU) to AWS IoT via a communication protocol like MQTT or HTTP, we need to create an entity for this device. On the AWS IoT platform this is called a “Thing”—its term for “a digital representation of a physical device or logical entity in AWS IoT.” I capitalize the term “Thing” for clarity in this piece, but AWS sometimes writes it lowercase: “thing.”

So, first we need to create a new Thing. From the AWS IoT dashboard left sidebar, click Manage -> All devices -> Things (Figure 2). Click one of the “Create Things” buttons (Figure 3), then select the “Create single Thing” option on the subsequent page.

Now, give your Thing a unique name in the “Thing name” text box. Leave the remaining options as they are, and press the “Next” button (Figure 4).

Figure 2
This is how you navigate to the Things section from the AWS IoT homepage. (Source: Amazon AWS)
Figure 2
This is how you navigate to the Things section from the AWS IoT homepage. (Source: Amazon AWS)
Figure 3
How to create a new Thing? Just click on Create things button from the Things section to start the Thing creation process. (Source: Amazon AWS)
Figure 3
How to create a new Thing? Just click on Create things button from the Things section to start the Thing creation process. (Source: Amazon AWS)
Figure 4
Here are the Thing properties you need to specify. We just need to specify the name in this step and leave the rest of the properties the same. (Source: Amazon AWS)
Figure 4
Here are the Thing properties you need to specify. We just need to specify the name in this step and leave the rest of the properties the same. (Source: Amazon AWS)

On AWS, we need a certificate configured for our Thing—in other words, a key, of sorts, that will help AWS associate a given Thing to our physical device when it’s trying to connect to the AWS service. There are several options available in this stepWe’ll choose the simplest, and let AWS create a new certificate for our thing. Choose the default option and press the “Next” button.

But creating a certificate is not enough. We need to attach a policy—essentially a set of rules—that will allow our device to access the AWS IoT resources. By default, there are no policies created. So, we’ll create one by clicking on the “Creat policy” button, which redirects you to a new page.

On the new webpage, you’ll have to specify certain options required to configure a policy. The first is the name of your policy. I am giving it a simple name for this tutorial: “Example_IoT_Policy.” Next, we have to configure something called a policy document. If you attach this policy to a certificate, the device using that certificate will have access to all the AWS IoT resources specified in the document.

Take a look at Figure 5 to see how I configured a policy for this tutorial. As this is just for learning purposes, I will give our device access to all AWS IoT resources for the following actions:

  • iot:Connect
  • iot:Publish
  • iot:Receive
  • iot:Subscribe

Giving access to all the resources is very simple in this case, as all that is needed is to type in * in the “Policy resource” text box for each action. The * signifies that whenever an IoT device tries to execute any of the above actions through AWS IoT, it is given full access to do so. The process works on something called topic names, similar to that of MQTT. So, when I publish a message through AWS IoT, I am allowed to do so if I use this policy

Finally, click on the “Create” button and you should see your newly-created policy listed under the AWS IoT policies section. Go to the previous window and select this newly-created policy (which should now be listed) and press the “Create Thing” button (Figure 6).

This will open a new pop-up window from which we can download the newly-created certificate file, public and private PPK keys (required to connect to AWS IoT), and the Root CA certificates (Figure 7). Download the following files, as they will be required when we connect our NodeMCU to AWS IoT:

  • Device Certificate
  • Both the Key files
  • Amazon Root CA 1 (RSA 2048-bit key)

Note that once you close the pop-up window, those files will not be available for download. Once you have downloaded all the necessary items, press the “Done” button. You have created your Thing and are finished with the setup. Congratulations! You have just created your very first device entity on AWS IoT. You should now see your Thing listed in the Things section (Figure 8). In the next section, we’ll cover the hardware setup for this project, followed by an explanation of the code.

Figure 5
The Policy Document configuration for our Example_Policy. For this tutorial, we will allow all IoT actions on any specified topic, signified by the * in the policy resource text box. (Source: Amazon AWS)
Figure 5
The Policy Document configuration for our Example_Policy. For this tutorial, we will allow all IoT actions on any specified topic, signified by the * in the policy resource text box. (Source: Amazon AWS)

Figure 6 We must attach the newly-created policy to our Thing to allow our NodeMCU device to connect to it. Select the policy and press the "Create thing" button.
Figure 6
We must attach the newly-created policy to our Thing to allow our NodeMCU device to connect to it. Select the policy and press the “Create thing” button.
Figure 7
You must download all the files which have been marked here. These will not be available once you close this window. They're required to establish a connection between our NodeMCU and AWS IoT.
Figure 7
You must download all the files which have been marked here. These will not be available once you close this window. They’re required to establish a connection between our NodeMCU and AWS IoT.
Figure 8
Once all the steps are complete, you should see your Thing listed in the Things section. In this case, you can see the Example_Thing I have created.
Figure 8
Once all the steps are complete, you should see your Thing listed in the Things section. In this case, you can see the Example_Thing I have created.
HARDWARE SETUP

The hardware setup for this project is fairly simple. This is what I would refer to as the Hello World! project for IoT development. We’ll use a DHT11 sensor connected to a NodeMCU development board to send temperature and humidity readings to AWS IoT every five second.

After you have all the components, connect them as shown in Figure 9. The figure shows a 3-pin DHT11 sensor. Another common pinout available has four pins, where the third pin from the right is the NC pin and hence requires no connections. I suggest you choose a 3-pin DHT11, as they’re widely available and easy to connect. At this point, we’re ready to dive into coding the NodeMCU device to allow it to connect to AWS IoT and publish the temperature and humidity readings.

Figure 9
This is a diagram of the NodeMCU and DHT11 Sensor setup. Please note that this is for a 3-pin DHT11 Sensor.
Figure 9
This is a diagram of the NodeMCU and DHT11 Sensor setup. Please note that this is for a 3-pin DHT11 Sensor.
CODE

Our code will connect our NodeMCU device to the specified Wi-Fi access point, and then establish a connection with our Thing using the security credentials that we provide. Once a Wi-Fi connection is established, we’ll obtain DHT11 temperature and humidity sensor readings and publish these on AWS IoT every five seconds, using the Node1/DHT11 topic. Moreover, we will print any messages which come in from the Node1/subscribe topic via the serial port.

This tutorial assumes that you have the Arduino IDE environment installed and configured to program the NodeMCU development board. A link to an excellent blog article on this topic has been provided in the article materials page on Circuit Cellar [2].

Importing the required libraries: We’ll use two external libraries which have to be downloaded separately. These are the DHT library [3] and the Arduino JSON library [4], whose Github links are on the Circuit Cellar article materials page. The DHT library enables our NodeMCU to communicate with the DHT11 sensor and fetch the temperature and humidity readings. The Arduino JSON library is used to format the MQTT Publish message as a JSON, in order to send multiple values in the same topic efficiently.

Moreover, we’ll add our own secrets.h file that will contain all the sensitive data—like the certificates, private key and CA1 cert—which are used to connect to AWS IoT, as well as the Wi-Fi SSID credentials, and so on. To create this file in Arduino IDE, go to the down arrow button on the top right and click “New Tab.” We’ll cover the contents of this file later. The code snippet for the library inclusion statements is shown in Listing 1.

Variable, constant and object declarations: Listing 2 shows the variables used in the program, grouped by their function. Let’s take a look here at the program’s more important functions. I’ll describe the important functions used in the program.

The NTPConnect function helps the NodeMCU get the current local time from the internet. This is required during the authentication process while establishing a connection with AWS IoT. Note that you must define the TIME_ZONE variable in your secrets.h file, as that will be required to convert the local time to UTC time. Listing 3 shows the NTPConnect function.

LISTING 1
These are the libraries that must be included for this program. Also shown is the sectrets.h file which contains all of the user-specific information such as SSID, passwords, and so forth.


// ------------------ Importing the required Libraries -------------------------

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>   // Library used - https://github.com/bblanchon/ArduinoJson
#include <time.h>
#include “DHT.h”   // Library used - https://github.com/markruys/arduino-DHT
#include “secrets.h”      // We will create this file to store all our sensitive data. Just go to the down arrow button on the top right and press on “New Tab”

// ---------------------------------------------------------------------------------------
Listing 2
These are the variables needed by the program as well as the various classes used.

// --------------------- Variable, Constants and Objects Declaration -------------
// DHT11 Sensor value variables
float temperature ;
float humidity ;

// Variables to implement publishing of sensor data to AWS IoT every 5 seconds
unsigned long lastMillis = 0;
unsigned long previousMillis = 0;
const long interval = 5000;
const int DHTPin = 14;

// variables to store the latest time fetched by the NTP Client.
time_t now;
time_t nowish = 1510592825;

// AWS Publish and subscribe topics
#define AWS_PUBLISH_TOPIC   “Node1/DHT11”
#define AWS_SUBSCRIBE_TOPIC “Node1/subscribe”

// WiFi SSL to add the certificates and the private pem key we retrieved from AWS
WiFiClientSecure net;
BearSSL::X509List cert(cacert);
BearSSL::X509List client_crt(client_cert);
BearSSL::PrivateKey key(privkey);

// Objects for pubsub and DHT11 sensor
PubSubClient client(net);
DHT dht;

// --------------------------------------------------------------------------
Listing 3
The NTPConnect routine connects to an NTP server on the internet and provides the program with the current time.

/ --------------------------------------------------------------------------

// NTPConnect : This function fetches the latest time.
// This is required for connecting with AWS IoT (Used for authentication)
 
void NTPConnect(void)
{
  Serial.print(“Setting time using SNTP”);
  configTime(TIME_ZONE * 3600, 0 * 3600, “pool.ntp.org”, “time.nist.gov”);
  now = time(nullptr);
  while (now < nowish)
  {
    delay(500);
    Serial.print(“.”);
    now = time(nullptr);
  }
  Serial.println(“done!”);
  struct tm timeinfo;
  gmtime_r(&now, &timeinfo);
  Serial.print(“Current time: “);
  Serial.print(asctime(&timeinfo));
}

// ----------------------------------------------------------------------------------------

The code to connect the NodeMCU to a Wi-Fi access point is well-documented in many ESP32 example programs. In the case of our Setup_WiFi function, the Wi-Fi credentials are taken from the secrets.h file.

The main purpose of callBackFunc is to print to the serial port any message that arrives from a topic to which our NodeMCU is subscribed (in other words, the Node1/subscribe topic).

The primary purpose of the connectToAWSIoT function is to:

  • Establish a connection with our Thing using the certificates and PEM keys that we downloaded.
  • Once the connection has been established, subscribe to the topic defined above (Node1/subscribe).


Listing 4
 is a code snippet of this function.

Once the connection has been established, the next step is to publish the DHT data to the AWS IoT. publishDHTReadings stores the DHT11 temperature and humidity readings (taken in the loop() function) in a JSON document, along with the latest timestamp. It publishes this data to the Node1/DHT11 topic. Listing 5 shows publishDHTReadings.

Listing 4
This routine is called connectToAWSIoT. 

// ---------------------------------------------------

// Connect to AWS IoT Thing entity we created.
void connectToAWSIoT()
{
  delay(3000);

  Setup_WiFi();
  NTPConnect();
  net.setTrustAnchors(&cert);
  net.setClientRSACert(&client_crt, &key);
  client.setServer(MQTT_HOST, 8883);
  client.setCallback(callbackFunc);
 
  Serial.println(“Connecting to AWS IOT”);
 
  while (!client.connect(THINGNAME))
  {
    Serial.print(“.”);
    delay(1000);
  }
 
  if (!client.connected()) {
    Serial.println(“AWS IoT Timeout!”);
    return;
  }
  // Subscribe to the topic specified above
  client.subscribe(AWS_SUBSCRIBE_TOPIC);
 
  Serial.println(“AWS IoT Connected!”);
}
// ---------------------------------------------------
Listing 5
This routine combines the sensor readings and time into a JSON file and publishes it to the AWS MQTT broker.

// ---------------------------------------------------

void publishDHTReadings()
{
  StaticJsonDocument<200> doc;
  doc[“time”] = millis();
  doc[“temperature”] = temperature;
  doc[“humidity”] = humidity;
  char jsonBuffer[512];
  serializeJson(doc, jsonBuffer); // print to client
 
  client.publish(AWS_PUBLISH_TOPIC, jsonBuffer);
}

// ---------------------------------------------------

As in all Arduino programs, there is a setup() function. In this function the serial port is initialized as well as the DHT11 sensor. Then the NodeMCU is connected to AWS using connectToAWSIoT.

The loop() function runs continuously after setup() is complete. It reads the current temperature and humidity readings from the DHT11 sensor, prints these readings to the serial monitor, checks if our device is connected to AWS IoT (if not, then it tries to re-establish a connection), and once a connection has been established, it calls the publishDHTReadings every five seconds.

The secrets.h file is used to store all the sensitive, user-specific variables needed by the program. These include:

  • Wi-Fi credentials (SSID and password for your Wi-Fi access point)
  • The name of the AWS IoT Thing that you defined. This will be used as the MQTT client’s name to establish a connection with AWS IoT Core.
  • The TIME_ZONE parameter (the difference between your time zone and UTC in hours).
  • MQTT_HOST will contain the AWS endpoint. It can be fetched by going to the AWS IoT Core settings under the Device data endpoint section.
  • The certificate, private key, and the Amazon Root CA1 certificate which we downloaded from AWS while creating our Thing. To get these items, open the downloaded file in a text editor and copy-paste their contents into the secrets.h file accordingly. You will find comments to assist you.

The program code for this article is available both as a download and via a link to its GitHub repository on Circuit Cellar‘s article materials page [5]. Upload the code to your NodeMCU and wait for a few seconds for your device to connect to AWS IoT.

The MQTT test client provided by AWS IoT is used to test this project. Subscribe to the Node1/DHT11 topic and you should be able to see the DHT11 sensor readings arriving every five seconds.

Moreover, you can publish a “Hello World!” message on the Node1/subscribe topic and it will be printed on the serial monitor. This demonstration is shown in Figure 10.

Figure 10
Here is a project demonstration showing how our device is publishing sensor values on AWS IoT and how we can subscribe and access messages from any subscribed topic.
Figure 10
Here is a project demonstration showing how our device is publishing sensor values on AWS IoT and how we can subscribe and access messages from any subscribed topic.
CONCLUSION

With this introduction, I hoped to help you understand how to connect an IoT device to AWS IoT. Hopefully it has been informative and valuable. Please contact me personally if you have questions, or if you would just like to connect and chat. 

REFERENCES
[1] Amazon AWS free subscription: https://aws.amazon.com/free/[2] NodeMCU Arduino setup: https://create.arduino.cc/projecthub/electropeak/getting-started-w-nodemcu-esp8266-on-arduino-ide-28184f[3] DHT Library: https://github.com/markruys/arduino-DHT[4] ArduinoJSON: https://github.com/bblanchon/ArduinoJson[5] GitHub Repository: https://github.com/Dhairya1007/AWS-IoT-Circuit-Cellar-Article-1

RESOURCES
NodeMCU | www.nodemcu.com

Code and Supporting Files

— ADVERTISMENT—

Advertise Here

PUBLISHED IN CIRCUIT CELLAR MAGAZINE • MAY 2023 #394 – Get a PDF of the issue

Keep up-to-date with our FREE Weekly Newsletter!

Don't miss out on upcoming issues of Circuit Cellar.


Note: We’ve made the Dec 2022 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Sponsor this Article
+ posts

Dhairya Parikh is an Electronics Engineer and an avid project developer. Dhairya makes projects that can bring a positive impact in a person’s life by making it easier. He is currently working as an IoT engineer. His projects are mainly related to IoT and machine learning. Dhairya can be contacted on dhairyaparikh1998@gmail.com

Supporting Companies

Upcoming Events


Copyright © KCK Media Corp.
All Rights Reserved

Copyright © 2024 KCK Media Corp.

AWS for IoT Projects

by Dhairya A. Parikh time to read: 12 min