In this article, you will learn to program a real smart table clock with Gmail notification, Fire Alarm, and temperature monitoring with Intel Edison.
Introduction
Ah! Another 'smart clock'!
You may well be thinking "what is the need of a clock project when a phone does it?"
Well, an IoT connected embedded device does many things which smart phones do not do that well. They respond to hardware and sensor events in faster and smarter ways. When you connect such devices to cloud, you get some awesome use cases which a simple mobile fails to do anyday.
This is a project I worked on to explore the exciting new possibilities with a clock and connecting it to IoT.
So what is so special about the clock?
- The clock shows date and time (which obviously all the clocks show)
- It shows temperature (which many table stand clocks show)
- It shows Gmail notification and can respond to that. For example, "coming home" mail turns on home light and "leaving home" mail turns off the home light.
- Shoots up fire alarm in case a very high and abnormal temperature pattern is detected.
Because the clock is connected to cloud, you can perform several tasks like scheduling an event, automatic notification and many more.
Before we start, let me make an honest confession. Like many of you, I am also new to IoT and Intel Edison Board. But when I was learning the IoT fundamentals, I saw most of the tutorials are Windows based. There are many differences when you develop an IoT framework on Linux than on Windows.
Even though Intel Edison runs on Yocto, configuring the board from a Linux platform and then coding needs many tweaks and twists. So, in this, I would more or less share my learning experience with you.
How to Work With Intel Edision Board in Linux
First, you need to install putty on your Linux system by using this command into your terminal:
$sudo apt-get install putty
Putty is a ssh and telnet client. If you want to access your system remotely, for example, suppose you have more than one system with ubuntu, one with windows and another with ssh server. Then you could access ssh server from the other systems using putty software by remotely login to the ssh server.
You need to configure putty in order to work with Intel edison board. To connect the Intel Edison board serially, you have to set the custom serial baud rate 115200 to the serial line /dev/ttyUSB0 because the default baud rate is 9600. To set a custom baud rate, you need to give a command on the terminal:
$stty -F /dev/ttyUSB0 115200
When you execute this line, you will get an error such as /dev/ttyUSB0 serial line permission denied. Because in the group category of /dev/ttyUSB0, serial line does not have read and write permission. Using the following command, you can see the permissions of any file.
$ls -l /dev/ttyUSB0
Attributes of /dev/ttyUSB0
Now you can reset the permission then in the Unix using chmod
command to see the changed permission of files, you have to use the command with -l
option.The following commands are:
$sudo chmod a+rw /dev/ttyUSB0
$ls -l /dev/ttyUSB0
Below is the screenshot:
Assign read and write permission to group category
So in the above screen, if you notice, group category assigned read and write permission. Now you can set the custom baud rate 115200 to the /dev/ttyUSB0 serial line. No error will be shown. This is the following screenshot:
Custom Baud rate 115200 set to /dev/ttyUSB0
Now configure the putty to access ssh server remotely, you can use the following command to open putty.
$sudo putty /dev/ttyUSB0 -serial -sercfg 115200
This command will open putty window and after pressing Enter, it asks for the login.
Putty window open
Asking for login name and password
Now, you have to do the following steps. I am demonstrating it using the following screenshots:
Firstly, give login name(root) and password. If the authentication is correct, then you got the Edison prompt. In the prompt, write 'ifconfig
' to configure and get the connected IP address.
Configuring putty
Using this IP address (192.168.1.2
), you can also login using the command:
$ssh root@192.168.1.2
Now to connect wi-fi, you need to write the following command:
$configure_edison –wifi
The wifi will be connected by giving the wifi password and this is the following screenshot:
Connecting wifi
Assigning wifi password
Now if you want to check the internet connection, you can ping the terminal using the command:
$ping google.com
Checking Wifi connection
Command prompt appears
When the edison prompt will return, it is ready to start with IoT (Internet of things). Here, I am demonstrating my work on IoT (smart clock for smart home). This project is developed by JavaScript environment with node.js module on Linux based (ubuntu).
Background
The smart clock does various types of smart work. It consists of two modules:
- It displays current date and current time on the LCD.
- Temperature indication with alarm, LCD display with background colour change and send mail to Gmail address.
In the first module, it displays time and date on the LCD with green background color. In the second module, if temperature crosses the limit temperature, then smart clock displays the temperature value with current time and generates notification with alarm, changes background colour of LCD (green to red) and sends email to the gmail address.
Using the Code
To display current time and date on the LCD, you have to connect LCD with the Intel Edison board. Intel Edison has I2C port, you have to connect the LCD with the I2C. It is just like that:
LCD connected with Intel Edison Board
Now, you need to remotely log in to the ssh server using putty (steps given above) and create a file using the command:
$vi clock.js
and write the following code to display date and time:
var currentdate=new Date();
var jsUpmI2cLcd=require('jsupm_i2clcd');
var lcd=new jsUpmI2cLcd.Jhd1313m1(6,0x3E,0x62);
var loop=function()
{
var time=currentdate.getHours()+":"+currentdate.getMinutes()+":"+
currentdate.getSeconds();
lcd.clear();
lcd.setColor(0,255,0);
lcd.setCursor(0,3);
lcd.write(time);
var date=currentdate.getFullYear()+"-"+('0'+
(currentdate.getMonth()+1)).slice(-2)+"-"+('0'+currectdate.getDate)).slice(-2);
lcd.setCursor(1,2);
lcd.write(date);
setTimeout(loop,500);
}
loop();
In the above code, I have used getHours()
, getMinutes
and getSeconds()
methods to display current hours, minute and second. Time is displayed on LCD starting from 0 number row and 3rd number column. Display time on the LCD uses the write
method. And getFullYear()
, getMonth()
and getDate()
methods to display current date. It displays date from the 2nd row.
To run this above code, you need to write the following command:
$node clock.js
This is the following output:
Current time and date displayed
Smart clock with date time
Smart clock can also display the current time and date in a different way using the following code:
var currentdate=new Date();
var jsUpmI2cLcd=require('jsupm_i2clcd');
var lcd=new jsUpmI2cLcd.Jhd131m1(6,0x3E,0x62);
var loop=function()
{
currentdate=new Date();
var targetTime=new Date(currentdate);
var timeZoneFromDB=+5.30;
var tzDifference=timeZoneFromDB*60+targetTime.getTimezoneOffset();
var offsetTime=new Date(targetTime.getTime()+tzDifference*60*1000);
var time=offsetTime.getHours()+":"+offsetTime.getMinutes()+":"+offsetTime.getSeconds();
lcd.clear();
lcd.setColor(0,255,0);
lcd.setCursor(0,3);
lcd.write(time);
var date=new Date();
lcd.setCursor(1,0);
lcd.write(date.toGMTString());
setTimeout(loop,1000);
}
loop();
Using the above code, we display the current time in HH:MM:SS and display the date into 'thu, 28 Jul 2016
'. Below is a screenshot:
Diffferent format time date display
- In the second module, you need to connect the temperature sensor groove connector with the Intel Edison board. You can connect it with any of the analog port of groove board. Here, I connect it with A0 port. Here, the image is as follows:
- Second, you have to connect buzzer groove connector with any of the data ports. Here, I connect it with D5 data port. Here, the image is as follows:
You can connect a LCD for the notification also. It displays the current temperature and background colour is set to green. If temperature crosses the threshold value, then background color changes to red. This is the way in which you can connect the LCD to the I2C port of Intel Edison board.
Afterwards, you need to connect the Intel Edison board and get into the Edision command prompt.
This is the screenshot:
Below is the code that you can use to read single value temperature using temperature sensor.
var mraa=require('mraa');
console.log('The version of mraa is:' + mraa.getVersion());
var AnalogPin0=new mraa.Aio(0);
var B=3975;
var a=AnalogPin0.read();
var resistance=(1023.0-a)*10000.0/a;
var temperature=1/(Math.log(resistance/10000.0)/B+1/298.15)-273.15;
var value=Math.round(temperature*100)/100;
console.log(value);
In the above code, signal of the temperature sensor is connected with A0. The B value is the value of thermistor.Formula (1023-a)*10000.0/a
is used to get the resistance of the sensor. Formula 1/(Math.log(resistance/10000.0)/B+1/298.15)-273.15
converts to temperature via NBSP datasheet catalog.
Below is the screenshot:
Now if the displayed temperature crosses the threshold value, then notification is generated. The code is as follows:
var digitalPin5=new mraa.Gpio(5);
digitalPin5.dir(mraa.DIR_OUT);
if(value>35)
{
digitalPin5.write(1);
}
You can write code for LCD color change notification. Below is the code:
var AnalogPin0=new mraa.Aio(0);
var jsUpmI2cLcd=require('jsupm_i2clcd');
var lcd=new jsUpmI2CLcd.Jhd1313m1(6,0x3E,0x62);
var B=3975;
var a=AnalogPin0.read();
var resistance=(1023.0-a)*10000.0/a;
var temperature=1/(Math.log(resistance/10000.0)/B+1/298.15)-273.15;
var value=Math.round(temperature*100)/100;
console.log(value);
var digitalPin5=new mraa.Gpio(5);
digitalPin5.dir(mraa.DIR_OUT);
lcd.clear();
lcd.setColor(0,255,0);
lcd.setCursor(0,1);
lcd.write("Temprature"+value);
if(temperature>25)
{
lcd.clear();
lcd.setColor(255,0,0);
lcd.setCursor(0,1);
lcd.write("Temprature"+value);
lcd.setColor(0,255,0);
lcd.setCursor(1,3);
lcd.write("It is hot");
digitalPin5.write(1);
}
In the above code, if the temperature is normal, then LCD displays in such a way.
Normal Temperature
If temperature crosses the threshold value, then red backcolor will turn on.
Temperature crossed threshold
But if you want to check the temperature frequently, then generate notification after crossing the threshold value, then the code is like that:
var mraa=require('mraa');
var jsUpmI2cLcd=require('jsupm_i2clcd');
var lcd=new jsUpmI2CLcd.Jhd1313m1(6,0x3E,0x62);
console.log('The varsion o0f mraa is:' + mraa.getVersion());
var AnalogPin0=new mraa.Aio(0);
var B=3975;
var digitalPin5=new mraa.Gpio(5);
digitalPin5.dir(mraa.DIR_OUT);
var loop=function()
{
var a=AnalogPin0.read();
var resistance=(1023.0-a)*10000.0/a;
var temperature=1/(Math.log(resistance/10000.0)/B+1/298.15)-273.15;
var value=Math.round(temperature*100)/100;
console.log(value);
lcd.clear();
lcd.setColor(0,255,0);
lcd.setCursor(0,1);
lcd.write("Temprature"+value);
if(value>25.0)
{
lcd.clear();
lcd.setColor(255,0,0);
lcd.setCursor(0,1);
lcd.write("Temprature"+value);
lcd.setCursor(1,3);
lcd.write("Its hot");
digitalPin5.write(1);
setTimeout(loop,500);
}
}
loop();
You can also vary the value of temperature sensor variation of temperature value. When you hold the increase temperature sensor value, the temperature is increasing and when you keep it far from the sensor, then the temperature is normal. Here, I show the temperature variation in the screenshot below:
Temperature variations are displayed on the terminal
Temperature displays on the Putty are as follows:
Temperature displays on putty
If temperature crosses the threshold value(25), then you can display a text message "Too hot
" on the terminal. This is as follows:
Temperature indication through text on terminal
To get the above text indication, we need to write the following code:
if(value>25.00)
{
lcd.clear();
lcd.setColor(255,0,0);
lcd.setCursor(0,3);
lcd.write(" "+ds);
console.log("Too hot");
lcd.setCursor(1,0);
lcd.write("Too hot"+ value);
digitalPin5.write(1);
}
I would like to add an Emoji image as an indication of temperature using the small change in coding.
This is the following output:
Temperature indication with Emoji image
To get the above output, we need to write the following code by small changes need to be done:
if(value>25.00)
{
lcd.clear();
lcd.setColor(255,0,0);
lcd.setCursor(0,3);
lcd.write(" "+ds);
console.write("Too hot "+ '\uD83D\uDE2D');
digitalPin5.write(1);
}
You can select any emoji image from the following link http://apps.timwhitlock.info/emoji/tables/unicode. On the page, we got unicode values of Emoji images. Click on unicode number, we got the surrogate values. To display the particular Emoji image, we need to write the value in the above mentioned way in coding.
You can combine the above coding such as current date and time and temperature display with text and alarm notification. This is the combined code:
var mraa=require('mraa');
var jsUpmI2cLcd=require('jsupm_i2clcd');
var lcd=new jsUpmI2cLcd.Jhd1313m1(6,0x3E,0x62);
console.log('The mraa version is:' + mraa.getVersion());
var Analogpin0=new mraa.Aio(0);
var digitalpin5=new mraa.Gpio(3);
digitalpin5.dir(mraa.DIR_OUT);
var B=3975;
var avg=0;
var n=0;
var loop=function()
{
var analogvalue=Analogpin0.read();
var registance=(1023.0-analogvalue)*10000.0/analogvalue;
var temperature=1/(Math.log(registance/10000.0)/B+1/298.15)-273.15;
var value=Math.round(temperature*100)/100;
avg=avg+value;
lcd.setColor(0,255,0);
lcd.setCursor(0,12);
lcd.write(""+value);
lcd.setCursor(1,0);
var d=new Date();
d=d.getTime()-(d.getTimezoneOffset()*60000);
d=new Date(d+(3600000*5.5));
lcd.write(""+d);
var ds=d.getHours()+":"+d.getMinutes()+":"+d.getSeconds();
lcd.write(ds);
lcd.setCursor(0,1);
lcd.write(""+ds);
if(value>35.0)
{
lcd.clear();
lcd.setColor(255,0,0);
lcd.setCursor(0,3);
lcd.write(""+ds);
lcd.setCursor(1,0);
lcd.write("Too hot"+ value);
digitalPin5.write(1);
}
setTimeout(loop,500);
}
loop();
These are the outputs:
When temperature is normal, then smart clock displays the current date time and temperature. This is the output:
Normal smart clock
If temperature crosses the threshold value, the smart clock displays current time and "Too hot
" message with value with red backcolor. This is the output:
Temperature notification
Now if you want to send information mail to a specific Gmail id or several ids, then you can use the general code:
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'das25391890@gmail.com',
pass: '123456'
}
});
var mailOptions = {
from: 'sender address',
to: 'das25391890@gmail.com' ,
subject: 'Password Reset',
html: 'Temperature is increasing do the needful :
<b>' + temporaryPassword + ' </b>'
};
transporter.sendMail(mailOptions, function (error, info) {
if(error){
return console.log(error);
}
console.log('Message sent:'+info.response);
In the above code, to send mail, I use nodemailer
module. It is the easy to use module to send mail with node.js through SMTP, nodemailer
is Windows friendly but you can use the nodemailer
in the Unix system also. To use the nodemailer
module, you need to install it with npm
, with the following commands:
$ sudo apt-get install npm
$npm install nodemailer
$npm install googleapis --save
$npm install google-auth-library --save
You have to set the turn on access for the less secure apps to the gmail address to receive the mail.
To send mail, you need a transporter object using SMTP transport, which is used in the above code to specify the service provider, user and password. If the mail will be sent successfully, then message send is displayed, otherwise error message is displayed. In the above code, the particular message will be sent to the specified das25391890@gmail.com mail id.
You can integrate the above send mail code with the temperature sensor using IOT application in such a way, if the temperature is gradually increasing and it crosses the limit, then you can send a mail to the authorised person's gmail address. You can write the integrated code in such a way:
var mraa=require('mraa');
var jsUpmI2cLcd=require('jsupm_i2clcd');
var lcd=new jsUpmI2cLcd.Jhd1313m1(6,0x3E,0x62);
console.log('The varsion o0f mraa is:' + mraa.getVersion());
var AnalogPin0=new mraa.Aio(0);
var B=3975;
var digitalPin5=new mraa.Gpio(5);
digitalPin5.dir(mraa.DIR_OUT);
var loop=function()
{
var a=AnalogPin0.read();
var resistance=(1023.0-a)*10000.0/a;
var temperature=1/(Math.log(resistance/10000.0)/B+1/298.15)-273.15;
var value=Math.round(temperature*100)/100;
console.log(value);
lcd.clear();
lcd.setColor(0,255,0);
lcd.setCursor(0,1);
lcd.write("Temprature"+value);
if(value>35.0)
{
lcd.clear();
lcd.setColor(0,255,0);
lcd.setCursor(0,1);
lcd.write("Temprature"+value);
digitalPin5.write(1);
}
setTimeout(loop,500);
}
loop();
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'das25391890@gmail.com',
pass: '123456'
}
});
var mailOptions = {
from: 'sender address',
to: 'das25391890@gmail.com' ,
subject: 'Password Reset',
html: 'Temperature is increasing do the needfull :
<b>' + temporaryPassword + ' </b>'
};
transporter.sendMail(mailOptions, function (error, info) {
if(error){
return console.log(error);
}
console.log('Message sent:'+info.response);
}
In the above code, if the temperature crosses 35, then mail will be sent to the specified gmail address. And on the terminal, the following message will displayed:
Email send message on the terminal
This is the screenshot of the mail in the gmail address:
Mail revived into gmail address
Here is my combined final product - a smart table clock. This makes my desk smarter. It displays the current date and time, temperature notification and gmail notification. Step by step, I display the product's different views.
Front view
Back view
Side view
Side view
3D View
Pen stand with current date time and normal temperature
Pen stand with current time and temperature text and alarm notification
Pen stand with time and mail notification for temperature
Try to make it according to your own way. It will make your desk smarter.