You’ve heard about this Internet of Things (IoT) trend and wanted an excuse to try a project. Well, me too. Actually, I have a goal to create a series of low cost climate/environment modules that capture various types of data like temperature, humidity and more. I want to take all this data and put it in the cloud where I can eventually build out dashboards, alerts and more.

Any good programmer knows to make it work before you make it scale. That’s where this post comes in. It's a simple IoT project using four things:

You can download all code from this tutorial from the GitHub project.

Connect the Sensor to the Arduino

The diagram below shows how the LM35 Temperature Sensor is connected to the Arduino Uno board. I used a breadboard to connect all this together. But I simplifyed the diagram so that you know what is connected to which pin. The LM35 has 3 pins.

  • The first pin goes to the 5V power pin on Arduino.
  • The third pin is the GND.
  • The middle pin is the VOUT which emits the values that we need to capture. We connect this to the Analog Pin (A0) on the Arduino Uno.

Temp log

Now we can write our Arduino code to read that value.

Retrieve the Readings from the Arduino Uno

Arduino requires a computer to interface via a serial port, such as over USB.

Again, we’re keeping this example simple. The Arduino code is straightforward as given below:

float temp;
int tempPin = 0;

void setup()
{
 Serial.begin(9600);
}

void loop()
{
 temp = analogRead(tempPin);
 temp = temp * 0.48828125;
 Serial.print(temp);
 Serial.println();
 delay(10000);
}

You will notice in the loop that every 10 seconds we are printing out the temperature value read from the Analog Pin (#0).

If you run the Serial Port Monitor that comes with the Arduino IDE, and if the Arduino is powered up and connected as per the diagram shown, the Temperature value is printed on the Serial Monitor.

Monitoring Arduino Data

Once the data appears we know that the Arduino setup is correct. All we need to do now is write a client program on the PC that interfaces with the Arduino, reads the values via the serial port, and then pushes them to the cloud database service.

Deploy a New Virtual Server with MongoDB

If you don't have a CenturyLink Cloud account yet, head over to our website and sign up for a free trial. You'll need it to access CenturyLink Cloud products.

Our first step is to deploy a new CenturyLink Cloud virtual server. Follow the steps below.

  1. Log into the CenturyLink Cloud control portal at https://control.ctl.io/
  2. On the left side menu, click Infrastructure and then Servers.

    Temp log

  3. On the left-hand side of the server panel, click on the region for the server we will provision.

  4. Click create and then server.
  5. Complete the setup form for your new server. Be sure to fill out the fields for server name and admin/root password.
  6. For operating system, select "CentOS 7 | 64-bit".
  7. Click create server.
  8. Your server provisioning request will enter the queue. You can watch the progress of your request on the screen. Your server is provisioned when the status of all tasks in the queue is complete.

    Temp log

  9. After your new server is provisioned, in the CenturyLink control portal, click Infrastructure on the left side menu, and then click Servers.

  10. Navigate to your new server and click on its name.
  11. Click the more menu, and then click add public ip.
  12. Check the box for SSH/SFTP (22).
  13. Click custom port... and then single port.
  14. Type "27017" in the blank box to open up the MongoDB server port.

    Temp log

  15. Click add public ip address.

Installing and Configuring MongoDB

  1. Navigate to your server in the CenturyLink Cloud control panel as in the previous section. Your server's public IP address will be noted on the screen.
  2. From a shell on your local machine, connect to your new server with the following command. Replace "YOUR.VPS.IP" with your server's public IP address.

    ssh [email protected]
    
  3. Install the MongoDB server software by running the following commands.

    $ yum install -y mongodb mongodb-server
    
  4. With your favorite text editor, open /etc/mongod.conf. Look for the line that begins "bind_ip" and comment it out. The top of your file should now look like this:

    ##
    ### Basic Defaults
    ##
    
    # Comma separated list of ip addresses to listen on (all local ips by default)
    #bind_ip = 127.0.0.1
    
  5. Start the MongoDB service by running the following command.

    $ service mongod start
    

Store the Readings in MongoDB

I decided to use Python to interface with the Arduino connected to my computer’s serial port. Here’s the plan:

  1. Install Python libraries and configure the Python script
  2. Initialize the serial port communication via which we read the temperature values that the Arduino unit emits. You need to know which serial port on your machine is interfaced to the Arduino.
  3. Every 10 seconds the code will read the value from the serial port. Obviously we can build more validations in the code, but this is good for now to demonstrate how all the pieces come together.
  4. Use the PyMongo library to post data into MongoDB.

First, install the pySerial and PyMongo libraries so you can read from the Arduino and write to MongoDB in Python.

pip install pyserial
pip install pymongo

Next, here is the code needed to read the temperature and record it in MongoDB. Be sure to configure the parameters near the top of the file to match your configuration. Create a new file in your favorite text editor called templog.py and edit it to look like the following.

import serial
import time
import datetime
from pymongo import MongoClient

# Configuration
serial_port          = '/dev/ttyACM0'
mongodb_host         = 'YOUR.MONGODB.HOST'
mongodb_db           = 'temperature'
temperature_location = "Mumbai-Kandivali"

# Connect to Serial Port for communication
ser = serial.Serial(serial_port, 9600, timeout=0)

# Connect to MongoDB
client = MongoClient(mongodb_host, 27017)
db = client[mongodb_db]
collection = db['templog']

# Setup a loop to send Temperature values at fixed intervals in seconds
fixed_interval = 10
while 1:
    try:
        # Temperature value obtained from Arduino + LM35 Temp Sensor
        temp_string = ser.readline().rstrip()

        # If we received a measurement, print it and send it to MongoDB.
        if temp_string:
            temperature_c = float(temp_string)
            doc_id = collection.insert_one({ 'temperature': temperature_c,
                                             'datetime': datetime.datetime.now(),
                                             'location': temperature_location}).inserted_id
            print str(doc_id) + ': ' + str(temperature_c) + ',' + temperature_location
    except serial.SerialTimeoutException:
        print('Error! Could not read the Temperature Value from unit')
    except ValueError:
        print('Error! Could not convert temperature to float')
    finally:
        time.sleep(fixed_interval)

Finally, run the script with the following command:

python templog.py

Note: If the Arduino Serial Monitor is running, your python script will be unable to access the serial port. Run only one of them at a time.

When using MongoDB, we first connect to the server, then we select a database and a collection in that database. The data is logged with the collection.insert_one() call. The fields being stored are the temperature in degrees Celsius, the timestamp of the measurement, and the location.

Check Your Data

The final step is to validate if our data is being transmitted successfully and stored in MongoDB. The Python code returns a confirmation message each time it checks the temperature, but to be extra sure we can go to the MongoDB client interface..

From the shell prompt on your virtual server, connect to MongoDB with this command:

mongo localhost/temperature

Run db.templog.find() at the prompt. It should look like this:

> db.templog.find()
{ "_id" : ObjectId("583370502aded5298bd0d5bd"), "location" : "Mumbai-Kandivali", "temperature" : 23.93, "datetime" : ISODate("2016-11-21T14:08:16.581Z") }
{ "_id" : ObjectId("5833705a2aded5298bd0d5be"), "location" : "Mumbai-Kandivali", "temperature" : 23.93, "datetime" : ISODate("2016-11-21T14:08:26.626Z") }
>

Arduino makes electronics prototyping fun. With languages like Python and a database like MongoDB, the process of collecting, transmitting, and saving the data in the cloud is made simple, too.