Table of Contents
So, you are doing a project to read some physical values using some sensors. Why not give your projects the ability to connect to cloud and make it an IoT project? Why not send the sensor data to cloud? In this post, we will do a simple IoT Project, where we will read the temperature and send it to cloud for storage. We will store the received temperature in AWS DynamoDB.
Few week back in a series of posts, I discussed how to connect to AWS IoT Core and send data from NodeMCU to AWS IoT Core. If you work on IoT, you would have already realized that it is also important to store the data. So, once we receive the data in AWS IoT Core, we need to store it somewhere.
There are two pre-requisites to this project:
- that you know how to send data to AWS IoT. Follow this post to see how to connect nodeMCU to AWS IoT Core.
- Network Time Protocol for Time Stamp.
In this project, our approach will be as follows:
- Read the Temperature in NodeMCU using a temperature Sensor (LM35 in this example)
- Form the JSON message with time stamp, that needs to be sent
- Send Data to AWS IoT
- From AWS IoT, send data to AWS DynamoDB
Read Temperature Sensor data in NodeMCU to send to cloud:
In this project, we are using LM35 to read the temperature. LM35 gives an analog output of 10mV/°C. To read about LM35 in details, read this article – Monitor Temperature with LM35 Temperature Sensor
So we will supply the LM35 with power and read the output pin(Vout) in the ADC input of nodeMCU, i.e., pin A0. The code to convert the voltage value to temperature in mentioned below in this post.
Circuit to connect LM35 with NodeMCU
The circuit connections are as follows:
NodeMCU | LM35 |
Vin | 1 |
GND | 3 |
A0 | 2 |
The Code:
We will now discuss the code to read the temperature and send it to the cloud. Compared to the code mentioned in the post Connect NodeMCU to AWS IoT Service , there will be a few changes in this code which we will discuss here. The entire code is divided into multiple files for ease of maintenance.
- AWS_IoT_temperature.ino
- config.h
- temperature.h
- wifi.h
You can download the entire code from GitHub. For the explanation of the remaining part of the code, you can refer to the post Connect NodeMCU to AWS IoT Service
There are a few changes that you need to make in the code, in the file wifi.h:
const char* ssid = "xxxxxx"; //Edit this line and put in your Wifi Name const char* password = "xxxxxxxx"; //Edit this line and put in your Wifi Password const char* AWS_endpoint = "xxxxxxxx.iot.us-east-1.amazonaws.com"; // Edit your AWS Endpoint here
Let us now move on to understand the changes in the code.
Read Temperature in NodeMCU:
For this project, we are using an LM35 sensor. This sensor gives an analog output of 10mV/degree C. So, we will read the sensor in the analog input of nodeMCU and calculate the temperature. In order to do so, we will need the following lines of code:
float readTemperatureInC(); int sensorPin = A0; // select the input pin for the potentiometer int sensorValue = 0; // variable to store the value coming from the sensor float temperatureInC = 0; int i = 0; float readTemperatureInC() { sensorValue = analogRead(sensorPin); Serial.println(sensorValue); temperatureInC = ((3.3/1024.0)*sensorValue)*100; //The nodeMCU ADC reference voltage is 3.3V for(i=0;i<10;i++) { sensorValue = analogRead(sensorPin); temperatureInC = (temperatureInC + ((3.3/1024.0)*sensorValue)*100)/2; } return temperatureInC; }
In the above code, we are creating a function that will return read the temperature sensor and return the temperature in degree Celcius.
Form the Message to send the Sensor Data to Cloud
We have read the temperature in the NodeMCU. Although we can send it directly to cloud, it won’t be very meaningful. Instead we will time stamp out readings and then send it. We will now form the message which we want to transmit. We will use three fields:
- Date
- Time
- Temperature
The following function does that for us:
void formMSGToTransmit() { String msg; timeClient.update(); unsigned long epochTime = timeClient.getEpochTime(); String formattedTime = timeClient.getFormattedTime(); String formattedDate = getDate(epochTime); count++; //create the message to be sent msg = "{\"Date\": \"" + formattedDate + "\",\n\"Time\":\"" + formattedTime + "\",\n\"Temperature\":\""; msg = msg + String(readTemperatureInC()) + "\"\n}"; msg.toCharArray(data,100); Serial.print("Publish message: "); Serial.println(data); }
This function uses the readTemperatureInC() function to get the temperature. This function creates a JSON message object that is then transmitted. The message looks like this:
{"Date": "2021-3-3",
"Time":"21:28:47",
"Temperature":"32.87"
}
This part of the code uses NTP to get the current network time. NTP is discussed in details here.
Once the code is ready, flash it on the NodeMCU. Then, verify whether you are receiving the data in AWS IoT Core. Follow this section in How to Connect NodeMCU to AWS IoT Core.
AWS IoT Rule for DynamoDB:
At this point, you should get the message which was created in the previous step in AWS IoT core. You are now ready to move on to the rules.
The steps involved are very simple but they are quite a few in number. I will list down the steps here, but if you want to see them, you can refer to this video below.
Steps to create AWS IoT Rule for DynamoDB:
- In the left hand navigation in AWS IoT Core, go to Act>Rules
- In the page that Opens, click Create
- Add a name for the rule and scroll down
- In the “Rule query statement” section, add the following statement:
SELECT Temperature FROM 'terraceTemp' WHERE Temperature>0
- The next section is “Set one or more actions“. Click on “Add Action“
- From the actions that are presented, select “Insert a message into a DynamoDB table” > Configure Action
- You will now need to configure the table to which you want to write the data. For the sake of this post, I will assume that you do not have any table for this data. So, click on “Create a new resource“. This will take you to DynamoDB
- Enter a table name, Partition key = “Date” and Sort key = “Time” without the double quotes
- Click on create and wait for the table to be created
- Go back to the AWS IoT page where you were creating the rule and click on refresh just before the
- “Create a new resource” option
- Now, select the table which you just created from drop down
- In “Partition key value“, enter ${Date}
- “Sort key value“= ${Time}
- In write message to this column, give a name of the column into which you want to write the data. I gave it “Tmpr“
- Operation = “INSERT“
- Scroll down and click on “Create Role“
- After the role is created, click on “Add Action“
Verify the Rule
That’s it. You are all set. Now, the next message received by AWS IoT core in the defined format will be pushed to Dynamo DB. Open the table which you had created and go to “Items“. You should see your data that looks similar to this
You are now successfully able to send your sensor data to the cloud. There are many other rules that can be created in AWS IoT to handle the incoming data. Do explore them. And do let me know in the comments below what you think of this post and your experience with the other rules.
Resources
Hi, I’m Vivek, a Senior Embedded Innovation Specialist. I have been working on Embedded Systems and IoT for the past 11 years. I love to share my knowledge and train those who are interested. Nerdyelectronics.com was started out of this interest. You can read my full profile in this link.