Home automation makes true the idea of the interconnected world at the touch of your fingertips. The way devices and appliances can be networked together to provide us with seamless control over all aspects of our home and more. For example:- Set a schedule to determine when you want devices to turn on and off.
New home automation technology can send alerts to your smartphone and notify you about unforeseen events while you're away from home. Such as light turned on/off, water leaks, visitors at your front your door, and even remotely turning on lights while you're on vacation, at work, or anywhere else.
The terminology of smart home refers to interconnected home consisting of devices that run off WiFi/Cellular to increase user experience. For example: Smart light switches, security systems, electrical appliances, and other devices that communicate with one another.
We will be building our own smart home prototype with a bunch of sensors and relays using Netduino3 WiFi Development Board and Ubidot's cloud service!
Project Hardware and Software Components:-- Netduino3 WiFi Development Board
The Netduino family is based on the Cortex-M Micro Processor running the .NETMicro Framework (NETMF) v4.3. Development can be done on both Windows, with Visual Studio, or with Xamarin Studio on Mac OS X. Netduino is packed with IO; including 22 General Purpose Input/Output (GPIO) ports, 6 of which support hardware Pulse Width Modulation (PWM) generation, 4 UARTs (serial communication), I2C, and SPI (Serial Peripheral Interface Bus).
Theyʼre also pin/port compatible with Arduino shields, opening a world possibilities.
Netduino can be powered either via the built-in USB adapter or the power barrel (VIN). If VIN is present, then that power is used, otherwise, it must be powered via USB. Netduino3/N3 will accept VIN of 5v to 12v. N2 will accept VIN of 5v to 9v.
Netduino3 Features:
Netduino3 Pin-out:-
For compatibility with Arduino hardware, Netduino has the same header and pin configuration as Arduino.
Netduino3 IDE Installation (Install Development Tools):
Visit the following links and follow the steps sequentially to install all the software's required to program the Netduino3 WiFi Development board.
Once your development environment is configured, make sure your board has the latest firmware on it. The firmware includes a customized .NETMF run-time specific to the board hardware. Ensuring that your Netduino has the latest firmware means that it will be up to date with the current Netduino-specific .NET Micro Framework run-time. Additionally, unless your Netduino has the latest firmware, you may have issues deploying your application to it.
- Ubidots IoT Platform
You can Connect, Develop, and Deploy IoT Applications with Ubidots Intuitive IoT Development Platform. The platform supports interactive, real-time data visualization (widgets), and an IoT App Builder that allows developers to extend the platform with their own HTML/JS code for private customization when desired. Device friendly APIs (accessed over HTTP/MQTT/TCP/UDP protocols) provide a simple and secure connection for sending and retrieving data to and from our cloud service in real-time. Ubidots’ time-series backend services are performance optimized for IoT data storage, computation, and retrieval.
Ubidots exists as an easy and affordable means to integrate the power of the IoT into your business or research.
You can even add conditional and complex business logic to your hardware with triggered webhooks for M2M communication, and SMS, Email, Telegram, and Slack alerts to keep operators on-the-ball and informed.
Ubidots supports HTTP, MQTT and TCP/UDP protocols. In our prototype project we are going to use HTTP protocol for sending and receiving data on Netduino board.
Restful API talks HTTP (the same protocol browsers use to communicate with web pages), a very standard way to communicate in the World Wide Web. The Ubidots API supports four HTTP methods:
GET - Used to retrieve information from the cloud
POST - Used to create a new element inside the cloud
PUT - Used to edit existing elements
DELETE - Used to delete existing elements
API access can be over HTTP or HTTPS, using the following URLs:
For educational users: http://things.ubidots.com/api/v1.6/
For business users: http://industrial.api.ubidots.com/api/v1.6/
or
For educational users: https://things.ubidots.com/api/v1.6/
For business users: https://industrial.api.ubidots.com/api/v1.6/
We will be mainly focused on receiving the relay/led control data from Ubidots using GET HTTP Method and sending/uploading the sensor data to Ubidots using POST HTTP Method. We will be using the educational Ubidots account for our project.
Ubidots for Education is a non-commercial product and is best applied to DIY projects, training and academic uses.
It can be accessed via the following URL:-
Relay is a digital electromagnetic switch capable of switching much higher voltage and current than general embedded development boards. The Grove-Relay module is a digital normally-open switch. i.e. When it is set to HIGH, the LED on the module will light up and relay will be closed allowing the current to flow. The peak voltage capability is 250VAC at 10 Amps and 30VDC at 10 Amps.
The Grove - Light Sensor module incorporates a Light Dependent Resistor (LDR). An LDR is a component that has a (variable) resistance that changes with the light intensity that falls upon it. This allows them to be used in light sensing circuits. Typically, the resistance of the LDR or Photo-resistor will decrease when the ambient light intensity increases. This means that the output signal from this module will be HIGH in bright light, and LOW in the dark.
This is a multi-functional sensor that gives you temperature and relative humidity information at the same time. It utilizes a TH02 sensor that can meet measurement needs of general purposes. It provides reliable readings when environment humidity condition in between 0-80% RH, and temperature condition in between 0-70°C, covering needs in most home and daily applications that don't contain extreme conditions.
This sensor is designed for comprehensive monitor over indoor air condition. It's responsive to a wide scope of harmful gases, as carbon monoxide, alcohol, acetone, thinner, formaldehyde and so on. Due to the measuring mechanism, this sensor can't output specific data to describe target gases' concentrations quantitatively. But it's still competent enough to check whether indoor air quality is good or not.
Wi-Fi Configuration Setting on Netduino3 Wi-Fi :-To begin with configuration you need NetduinoDeploy software.
Download Link You will find the software under following heading "Firmware Updater and Configuration Tool".
For using this software you have to put the Netduino board into DFU mode. And also you will be required to check that when you put your Netduino into DFU mode it is recognized by your PC. To put Netduino in DFU mode you need to press switch available on board then plug USB power cable keeping button pressed and after this release.
Before updating the Wi-Fi setting you can use the same software to update the firmware inside your Netduino board. Then proceed with adding WiFi setting according to your router. Adding WiFi Network setting, for my router, it is WPA2 and 128bit key encryption.
Visit Following link for more information on updating the Wi-Fi Setting:-
How to Connect the Netduino3 WiFi to the WiFi Router
Incase your Netduino board DFU mode is not recognised by your PC you have to update the bootloader.
Also replace your existing Netduino bootloader driver with WinUSB
Blinky Program Tutorial:-- Step 1:- Launch Visual Studio and create a new solution of type Visual C# > Micro Framework > Netduino Application (Universal) and name it whatever you want:
- Step 2:- Checking the program.cs file for the default code generated.
You will see the following default code:-
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
namespace Led_Blink_Example
{
public class Program
{
public static void Main()
{
// write your Main code here
}
}
}
}
At the beginning of this default code generated you will see some libraries are included (this are also called references) which are:-
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
Those libraries/references have unique functionality associated for them. Like for our blinking code we require only the following libraries:-
using System.Threading;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
So our final blinking code for the onboard led on the Netduino3 Wi-Fi board is:-
using System.Threading;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
namespace Led_Blink_Example
{
public class Program
{
// An output port allows you to write (send a signal) to a pin
static OutputPort _led = new OutputPort(Pins.ONBOARD_LED, false);
public static void Main()
{
// write your Main code here
// turn the LED off initially
_led.Write(false);
// run forever
while (true)
{
// turn the LED off
_led.Write(false);
Thread.Sleep(500);
// turn the LED on
_led.Write(true);
Thread.Sleep(500);
}
}
}
}
Copy paste the above code inside the program.cs and then connect the Netduino3 board via USB to your computer.
Click on the "Properties" tab and check the Target Framework is .Net Micro Framework 4.3 or not:-
Then also check your Netduino3 board is visible or not:-
- Step 3: Running the code by clicking on the "Start" button
- Step 4:- Adding the references if required. Like for this blinking project as i told you we required only some of the references but what if required a lot of them then you can install it via "References" tab.
For the internet connection part i have the used the code available here.
using System; //For functions like Random number generator
using System.Net; //For http web request, ip address mthods
using System.Text; //For Encoding.UTF8.GetBytes method
using System.IO; //For StreamReader methods
using System.Threading; //For Thread methods like Sleep
using Microsoft.SPOT; //For Serial Debug method
using Microsoft.SPOT.Hardware; //For input/Output functions like OutputPort
using SecretLabs.NETMF.Hardware.Netduino; //For input/output functions like pin definition Pins.ONBOARD_LED
using Microsoft.SPOT.Net.NetworkInformation; //for networkinterface and related methods
//Your project name should always match the below namespace name
namespace UbidotsIntervalUploading
{
public class Program
{
public static void Main()
{
OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
led.Write(true); // turn on the LED
Thread.Sleep(1000); // sleep for 1000ms
led.Write(false); // turn off the LED
Thread.Sleep(1000); // sleep for 250ms
led.Write(true); // turn on the LED
Thread.Sleep(1000); // sleep for 1000ms
led.Write(false); // turn off the LED
Thread.Sleep(1000); // sleep for 1000ms
Debug.Print("Ready to Run.....!");
App app = new App();
app.Run();
while (app.IsRunning)
{
led.Write(true); // turn on the LED
Thread.Sleep(250); // sleep for 250ms
led.Write(false); // turn off the LED
Thread.Sleep(250); // sleep for 250ms
}
while (app.ipCheck == false)
{
app.Run();
Thread.Sleep(1000);
}
//led.Write(false); // turn off the LED onboard the Netduino
//Debug.Print("Turn off the LED onboard the Netduino");
while (true)
{
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
app.MakeWebRequest(ubidotsURL);
//Random number generator
Random rnd = new Random();
string sensor1Label = "lightLevel";
//Generates 0 to 100 random number for light intensity which is in percentage
int sensor1Data = rnd.Next(100);
string sensor2Label = "airQuality";
//Generates 0 to 1023 random number for air Quality
int sensor2Data = rnd.Next(1023);
app.UploadWebRequest(ubidotsURL, sensor1Label, sensor1Data, sensor2Label, sensor2Data);
string controlVariable1 = "relay1button";
int dataReceived = app.ReceiveWebRequest(ubidotsURL, controlVariable1);
Debug.Print("");
Debug.Print("Data Received:- " + dataReceived);
if (dataReceived == 1)
{
Debug.Print("Turning the Relay1 ON Connected to Pin D2");
}
else if (dataReceived == 0)
{
Debug.Print("Turning the Relay1 OFF Connected to Pin D2");
}
Thread.Sleep(2500);
}
}
}
public class App
{
NetworkInterface[] _interfaces;
//public bool IsRunning { get; set; }
bool _IsRunning;
public bool IsRunning
{
get { return _IsRunning; }
set { _IsRunning = value; }
}
bool _ipCheck;
public bool ipCheck
{
get { return _ipCheck; }
set { _ipCheck = value; }
}
public void Run()
{
this.IsRunning = true;
Debug.Print("Initializing the networks...");
bool goodToGo = InitializeNetwork();
this.ipCheck = goodToGo;
if (goodToGo)
{
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
MakeWebRequest(ubidotsURL);
}
this.IsRunning = false;
}
protected bool InitializeNetwork()
{
if (Microsoft.SPOT.Hardware.SystemInfo.SystemID.SKU == 3)
{
Debug.Print("Wireless tests run only on Device");
return false;
}
Debug.Print("Getting all the network interfaces.");
_interfaces = NetworkInterface.GetAllNetworkInterfaces();
// debug output
ListNetworkInterfaces();
// loop through each network interface
foreach (var net in _interfaces)
{
// debug out
ListNetworkInfo(net);
switch (net.NetworkInterfaceType)
{
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
// check for an IP address, try to get one if it's empty
return CheckIPAddress(net);
}
// if we got here, should be false.
return false;
}
public void UploadWebRequest(string url, string sensor1, int sensor1Data, string sensor2, int sensor2Data)
{
string payload = "{\"" + sensor1 + "\": " + sensor1Data + ",\"" + sensor2 + "\": " + sensor2Data + "}";
Debug.Print("JSON String is " + payload);
var request = (HttpWebRequest)WebRequest.Create(url);
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
public int ReceiveWebRequest(string url, string controlVar)
{
string requestUrl = url + controlVar + "/" + "lv";
Debug.Print("Making a Get Request to:- " + requestUrl);
//"http://things.ubidots.com/api/v1.6/devices/testDevice/relay1button/lv";
var request = (HttpWebRequest)WebRequest.Create(requestUrl);
request.Method = "GET";
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
var httpResponse = (HttpWebResponse)request.GetResponse();
int dataReceived = 0;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
string resultData = result;
Debug.Print("Relay Data:- " + resultData + " length:- " + resultData.Length);
double temp = double.Parse(resultData);
dataReceived = (int)temp;
}
return dataReceived;
}
public void MakeWebRequest(string url)
{
var value = 25;
string sensor = "temperature";
string payload = "{\"" + sensor + "\": " + value + "}";
Debug.Print("JSON String is " + payload);
//string payload = "{\"temperature\": 56, \"luminosity\": {\"value\":16}}";
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
//Creating a byte array for our payload for length calculation
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
protected bool CheckIPAddress(NetworkInterface net)
{
int timeout = 10000; // timeout, in milliseconds to wait for an IP. 10,000 = 10 seconds
// check to see if the IP address is empty (0.0.0.0). IPAddress.Any is 0.0.0.0.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("No IP Address");
if (net.IsDhcpEnabled)
{
Debug.Print("DHCP is enabled, attempting to get an IP Address");
// ask for an IP address from DHCP [note this is a static, not sure which network interface it would act on]
int sleepInterval = 10;
int maxIntervalCount = timeout / sleepInterval;
int count = 0;
while (IPAddress.GetDefaultLocalAddress() == IPAddress.Any && count < maxIntervalCount)
{
Debug.Print("Sleep while obtaining an IP");
Thread.Sleep(10);
count++;
};
// if we got here, we either timed out or got an address, so let's find out.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("Failed to get an IP Address in the alotted time.");
return false;
}
Debug.Print("Got IP Address: " + net.IPAddress.ToString());
return true;
//NOTE: this does not work, even though it's on the actual network device. [shrug]
// try to renew the DHCP lease and get a new IP Address
//net.RenewDhcpLease ();
//while (net.IPAddress == "0.0.0.0") {
// Thread.Sleep (10);
//}
}
else
{
Debug.Print("DHCP is not enabled, and no IP address is configured, bailing out.");
return false;
}
}
else
{
Debug.Print("Already had IP Address: " + net.IPAddress.ToString());
return true;
}
}
protected void ListNetworkInterfaces()
{
foreach (var net in _interfaces)
{
switch (net.NetworkInterfaceType)
{
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
}
}
protected void ListNetworkInfo(NetworkInterface net)
{
Debug.Print("MAC Address: " + BytesToHexString(net.PhysicalAddress));
Debug.Print("DHCP enabled: " + net.IsDhcpEnabled.ToString());
Debug.Print("Dynamic DNS enabled: " + net.IsDynamicDnsEnabled.ToString());
Debug.Print("IP Address: " + net.IPAddress.ToString());
Debug.Print("Subnet Mask: " + net.SubnetMask.ToString());
Debug.Print("Gateway: " + net.GatewayAddress.ToString());
if (net is Wireless80211)
{
var wifi = net as Wireless80211;
Debug.Print("SSID:" + wifi.Ssid.ToString());
}
}
private static string BytesToHexString(byte[] bytes)
{
string hexString = string.Empty;
// Create a character array for hexidecimal conversion.
const string hexChars = "0123456789ABCDEF";
// Loop through the bytes.
for (byte b = 0; b < bytes.Length; b++)
{
if (b > 0)
hexString += "-";
// Grab the top 4 bits and append the hex equivalent to the return string.
hexString += hexChars[bytes[b] >> 4];
// Mask off the upper 4 bits to get the rest of it.
hexString += hexChars[bytes[b] & 0x0F];
}
return hexString;
}
}
}
References Required for this project are shown in the below image; installL it before clicking on the "Start" button:-
There are two classes in our project - Program and App. Since Netduino has sophisticated multi-threading support (especially for an MCU platform), it's useful for a more elegant solution that also saves on power consumption.
Class App has network connection functions some of which are protected while others are Public. Only the Public functions can be called from other class. We are going to call MakeWebRequest, UploadWebRequest and ReceiveWebRequest functions from our Main function inside the class Program.
- public void Run()
Call all the network functions to connect to the Wi-Fi SSID and get an IP Address. If everything is good call MakeWebRequest to send a request to a web API using HTTP methods.
public void Run()
{
this.IsRunning = true;
Debug.Print("Initializing the networks...");
bool goodToGo = InitializeNetwork();
this.ipCheck = goodToGo;
if (goodToGo)
{
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/testDevice/";
MakeWebRequest(ubidotsURL);
}
this.IsRunning = false;
}
- protected bool InitializeNetwork()
Prints each Network Interface (for e.g. Ethernet, WiFi or Unknown) information and checks for IP Address.
protected bool InitializeNetwork()
{
if (Microsoft.SPOT.Hardware.SystemInfo.SystemID.SKU == 3)
{
Debug.Print("Wireless tests run only on Device");
return false;
}
Debug.Print("Getting all the network interfaces.");
_interfaces = NetworkInterface.GetAllNetworkInterfaces();
// debug output
ListNetworkInterfaces();
// loop through each network interface
foreach (var net in _interfaces)
{
// debug out
ListNetworkInfo(net);
switch (net.NetworkInterfaceType)
{
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
// check for an IP address, try to get one if it's empty
return CheckIPAddress(net);
}
// if we got here, should be false.
return false;
}
- protected bool CheckIPAddress(NetworkInterface net)
To check whether DHCP is enabled and we got IP Address or not and if we got IP Address print it on Serial Monitor.
protected bool CheckIPAddress(NetworkInterface net)
{
int timeout = 10000; // timeout, in milliseconds to wait for an IP. 10,000 = 10 seconds
// check to see if the IP address is empty (0.0.0.0). IPAddress.Any is 0.0.0.0.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("No IP Address");
if (net.IsDhcpEnabled)
{
Debug.Print("DHCP is enabled, attempting to get an IP Address");
// ask for an IP address from DHCP [note this is a static, not sure which network interface it would act on]
int sleepInterval = 10;
int maxIntervalCount = timeout / sleepInterval;
int count = 0;
while (IPAddress.GetDefaultLocalAddress() == IPAddress.Any && count < maxIntervalCount)
{
Debug.Print("Sleep while obtaining an IP");
Thread.Sleep(10);
count++;
};
// if we got here, we either timed out or got an address, so let's find out.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("Failed to get an IP Address in the alotted time.");
return false;
}
Debug.Print("Got IP Address: " + net.IPAddress.ToString());
return true;
//NOTE: this does not work, even though it's on the actual network device. [shrug]
// try to renew the DHCP lease and get a new IP Address
//net.RenewDhcpLease ();
//while (net.IPAddress == "0.0.0.0") {
// Thread.Sleep (10);
//}
}
else
{
Debug.Print("DHCP is not enabled, and no IP address is configured, bailing out.");
return false;
}
}
else
{
Debug.Print("Already had IP Address: " + net.IPAddress.ToString());
return true;
}
}
- protected void ListNetworkInterfaces()
To check which Interface (for e.g. Ethernet, WiFi or Unknown) is present for Internet Connection.
protected void ListNetworkInterfaces()
{
foreach (var net in _interfaces)
{
switch (net.NetworkInterfaceType)
{
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
}
}
- protected void ListNetworkInfo(NetworkInterface net)
Prints all the network information like MAC Address, IP Address, Wi-Fi SSID, etc.
protected void ListNetworkInfo(NetworkInterface net)
{
Debug.Print("MAC Address: " + BytesToHexString(net.PhysicalAddress));
Debug.Print("DHCP enabled: " + net.IsDhcpEnabled.ToString());
Debug.Print("Dynamic DNS enabled: " + net.IsDynamicDnsEnabled.ToString());
Debug.Print("IP Address: " + net.IPAddress.ToString());
Debug.Print("Subnet Mask: " + net.SubnetMask.ToString());
Debug.Print("Gateway: " + net.GatewayAddress.ToString());
if (net is Wireless80211)
{
var wifi = net as Wireless80211;
Debug.Print("SSID:" + wifi.Ssid.ToString());
}
}
- private static string BytesToHexString(byte[] bytes)
To print the MAC Address we have to convert the Bytes to Hex.
private static string BytesToHexString(byte[] bytes)
{
string hexString = string.Empty;
// Create a character array for hexidecimal conversion.
const string hexChars = "0123456789ABCDEF";
// Loop through the bytes.
for (byte b = 0; b < bytes.Length; b++)
{
if (b > 0)
hexString += "-";
// Grab the top 4 bits and append the hex equivalent to the return string.
hexString += hexChars[bytes[b] >> 4];
// Mask off the upper 4 bits to get the rest of it.
hexString += hexChars[bytes[b] & 0x0F];
}
return hexString;
}
- public void MakeWebRequest(string url)
This function is made public so that we can call it inside our main function situated in the Class Program. It sends a constant data in json format to Ubidots using HTTP Post Method.
The easiest way to send values to Ubidots is specifying your Device label in the URL and making a POST request to it:
http://things.ubidots.com/api/v1.6/devices/{LABEL_DEVICE}/
Data has to be uploaded in the following format:-
POST /api/v1.6/devices/{LABEL_DEVICE}/?token={TOKEN} HTTP/1.1
Host: things.ubidots.com
Content-Type: application/json
Content-Length: 76
{"temperature": 10, "luminosity": {"value":10}, "wind_speed": [{"value": 11, "timestamp":10000}, {"value": 12, "timestamp":13000}]}
And this is how we call our above function:-
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
app.MakeWebRequest(ubidotsURL);
The constant value updated in 25 for temperature variable inside the "netduino_smart_home" device label in my ubidots account.
{"temperature": 25}
public void MakeWebRequest(string url)
{
var value = 25;
string sensor = "temperature";
string payload = "{\"" + sensor + "\": " + value + "}";
Debug.Print("JSON String is " + payload);
//string payload = "{\"temperature\": 56, \"luminosity\": {\"value\":16}}";
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
//Creating a byte array for our payload for length calculation
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
- public void UploadWebRequest(string url, string sensor1, int sensor1Data, string sensor2, int sensor2Data)
This is similar to the MakeWebRequest function except that it takes the sensor's values to upload it to Ubidots. This function is used to upload the sensor's data to Ubidots IoT Platform using HTTP POST Method.
The easiest way to send values to Ubidots is specifying your Device label in the URL and making a POST request to it:
http://things.ubidots.com/api/v1.6/devices/{LABEL_DEVICE}/
Only two sensors data can be uploaded using this function. We are uploading random values using this function to "lightLevel" and "airQuality" variables inside the "netduino_smart_home" device label in my ubidots account.
We can call this function in the following way:-
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
//Random number generator
Random rnd = new Random();
string sensor1Label = "lightLevel";
//Generates 0 to 100 random number for light intensity which is in percentage
int sensor1Data = rnd.Next(100);
string sensor2Label = "airQuality";
//Generates 0 to 1023 random number for air Quality
int sensor2Data = rnd.Next(1023);
app.UploadWebRequest(ubidotsURL, sensor1Label, sensor1Data, sensor2Label, sensor2Data);
The function is as follows:
public void UploadWebRequest(string url, string sensor1, int sensor1Data, string sensor2, int sensor2Data)
{
string payload = "{\"" + sensor1 + "\": " + sensor1Data + ",\"" + sensor2 + "\": " + sensor2Data + "}";
Debug.Print("JSON String is " + payload);
var request = (HttpWebRequest)WebRequest.Create(url);
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
- public int ReceiveWebRequest(string url, string controlVar)
This function is used to receive the data from Ubidots IoT Platform using HTTP GET Method.
To get the values of a variable using its label, make a GET request to:
http://things.ubidots.com/api/v1.6/devices/{LABEL_DEVICE}/{VARIABLE_LABEL}/values
But this will return all the values of that control variable.
I am concerned only what is the last value which is return to the control variable.
To get the last value of a variable using its label, make a GET request to:
http://things.ubidots.com/api/v1.6/devices/{LABEL_DEVICE}/{VARIABLE_LABEL}/lv
Http Request to get values using the variable’s label:-
GET /api/v1.6/devices/{LABEL_DEVICE}/{VARIABLE_LABEL}/values?token={TOKEN} HTTP/1.1
Host: things.ubidots.com
We can call this function in the following way:-
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
string controlVariable1 = "relay1button";
int dataReceived = app.ReceiveWebRequest(ubidotsURL, controlVariable1);
Debug.Print("");
Debug.Print("Data Received:- " + dataReceived);
The function is as follows:
public int ReceiveWebRequest(string url, string controlVar)
{
string requestUrl = url + controlVar + "/" + "lv";
Debug.Print("Making a Get Request to:- " + requestUrl);
//"http://things.ubidots.com/api/v1.6/devices/testDevice/relay1button/lv";
var request = (HttpWebRequest)WebRequest.Create(requestUrl);
request.Method = "GET";
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
var httpResponse = (HttpWebResponse)request.GetResponse();
int dataReceived = 0;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
string resultData = result;
Debug.Print("Relay Data:- " + resultData + " length:- " + resultData.Length);
double temp = double.Parse(resultData);
dataReceived = (int)temp;
}
return dataReceived;
}
Serial Debugging for this project:-
Whenever the json data is correct and the data is uploaded successfully you will get {"status_code": 201} for that sensor data variable.
The output is as follows:-
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
The thread '<No Name>' (0x4) has exited with code 0 (0x0).
Ready to Run.....!
Initializing the networks...
Getting all the network interfaces.
Found 802.11 WiFi Interface
MAC Address: 60-D7-E3-A0-04-02
DHCP enabled: True
Dynamic DNS enabled: False
IP Address: 192.168.1.101
Subnet Mask: 255.255.255.0
Gateway: 192.168.1.1
SSID:LittleHeart
Found 802.11 WiFi Interface
Already had IP Address: 192.168.1.101
JSON String is {"temperature": 25}
Response:- {"temperature": [{"status_code": 201}]}
JSON String is {"temperature": 25}
The thread '<No Name>' (0x7) has exited with code 0 (0x0).
Response:- {"temperature": [{"status_code": 201}]}
JSON String is {"lightLevel": 57,"airQuality": 871}
Response:- {"lightlevel": [{"status_code": 201}], "airquality": [{"status_code": 201}]}
Making a Get Request to:- http://things.ubidots.com/api/v1.6/devices/netduino_smart_home/relay1button/lv
Relay Data:- 0.0 length:- 3
Data Received:- 0
JSON String is {"temperature": 25}
The thread '<No Name>' (0x8) has exited with code 0 (0x0).
The thread '<No Name>' (0x9) has exited with code 0 (0x0).
The thread '<No Name>' (0xa) has exited with code 0 (0x0).
Response:- {"temperature": [{"status_code": 201}]}
JSON String is {"lightLevel": 79,"airQuality": 260}
Response:- {"lightlevel": [{"status_code": 201}], "airquality": [{"status_code": 201}]}
Making a Get Request to:- http://things.ubidots.com/api/v1.6/devices/netduino_smart_home/relay1button/lv
The thread '<No Name>' (0xb) has exited with code 0 (0x0).
Relay Data:- 0.0 length:- 3
Data Received:- 1
JSON String is {"temperature": 25}
Response:- {"temperature": [{"status_code": 201}]}
JSON String is {"lightLevel": 47,"airQuality": 762}
Ubidots Account Configuration:-
This code automatically will create a new device inside the Devices Tab of Ubidots account with all the variables as named inside the code. But to do so you have to change the token inside the code with your ubidots account token key.
We have named our device as following inside the code :-
string deviceLabel = "netduino_smart_home";
i.e see the following code line present in all the three functions- UploadWebRequest, ReceiveWebRequest and MakeWebRequest:-
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Now run your Uploading/Receiving Data from Ubidots code. Now if you click on the Devices tab you will see that a new device is created but still your program will stop abruptly. Since the uploading sensor variables like air quality, light level and temperature is created automatically when you upload a value to this variables. But the control variable "relay1button" for which we are requesting Ubidots to receive it's last value is not present so you have to manually create it.
Add an imageDelete this imagestring controlVariable1 = "relay1button";
int dataReceived = app.ReceiveWebRequest(ubidotsURL, controlVariable1);
Debug.Print("");
Debug.Print("Data Received:- " + dataReceived);
Now to visualize the sensor data and the button for our control variable we have to create widgets inside our Dashboard in your Ubidots account. After completing all the widgets in your Dashboard always click on the control variables widgets so that they can have some default value which you can read using Netduino.
Let's write a code to control our on-board led using the relay1button widget we created on our Ubidot's Dashboard!
Netduino On-Board LED Control from Ubidots:-The main code for this project:-
using System; //For functions like Random number generator
using System.Net; //For http web request, ip address mthods
using System.Text; //For Encoding.UTF8.GetBytes method
using System.IO; //For StreamReader methods
using System.Threading; //For Thread methods like Sleep
using Microsoft.SPOT; //For Serial Debug method
using Microsoft.SPOT.Hardware; //For input/Output functions like OutputPort
using SecretLabs.NETMF.Hardware.Netduino; //For input/output functions like pin definition Pins.ONBOARD_LED
using Microsoft.SPOT.Net.NetworkInformation; //for networkinterface and related methods
//Your project name should always match the below namespace name
namespace UbidotsIntervalUploading
{
public class Program
{
public static void Main()
{
OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
led.Write(true); // turn on the LED
Thread.Sleep(1000); // sleep for 250ms
led.Write(false); // turn off the LED
Thread.Sleep(1000); // sleep for 250ms
led.Write(true); // turn on the LED
Thread.Sleep(500); // sleep for 250ms
led.Write(false); // turn off the LED
Thread.Sleep(1000); // sleep for 250ms
Debug.Print("Ready to Run.....!");
App app = new App();
app.Run();
while (app.IsRunning)
{
led.Write(true); // turn on the LED
Thread.Sleep(250); // sleep for 250ms
led.Write(false); // turn off the LED
Thread.Sleep(250); // sleep for 250ms
}
while (app.ipCheck == false)
{
app.Run();
Thread.Sleep(1000);
}
led.Write(false); // turn off the LED onboard the Netduino
Debug.Print("Turn off the LED onboard the Netduino");
while (true)
{
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
string controlVariable1 = "relay1button";
int dataReceived = app.ReceiveWebRequest(ubidotsURL, controlVariable1);
Debug.Print("");
Debug.Print("Data Received:- " + dataReceived);
if (dataReceived == 1)
{
Debug.Print("Turn ON the LED onboard the Netduino");
led.Write(true); // turn ON the LED onboard the Netduino
}
else if (dataReceived == 0)
{
Debug.Print("Turn OFF the LED onboard the Netduino");
led.Write(false); // turn OFF the LED onboard the Netduino
}
Thread.Sleep(2500);
}
}
}
public class App
{
NetworkInterface[] _interfaces;
//public bool IsRunning { get; set; }
bool _IsRunning;
public bool IsRunning
{
get { return _IsRunning; }
set { _IsRunning = value; }
}
bool _ipCheck;
public bool ipCheck
{
get { return _ipCheck; }
set { _ipCheck = value; }
}
public void Run()
{
this.IsRunning = true;
Debug.Print("Initializing the networks...");
bool goodToGo = InitializeNetwork();
this.ipCheck = goodToGo;
if (goodToGo)
{
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
MakeWebRequest(ubidotsURL);
}
this.IsRunning = false;
}
protected bool InitializeNetwork()
{
if (Microsoft.SPOT.Hardware.SystemInfo.SystemID.SKU == 3)
{
Debug.Print("Wireless tests run only on Device");
return false;
}
Debug.Print("Getting all the network interfaces.");
_interfaces = NetworkInterface.GetAllNetworkInterfaces();
// debug output
ListNetworkInterfaces();
// loop through each network interface
foreach (var net in _interfaces)
{
// debug out
ListNetworkInfo(net);
switch (net.NetworkInterfaceType)
{
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
// check for an IP address, try to get one if it's empty
return CheckIPAddress(net);
}
// if we got here, should be false.
return false;
}
public void UploadWebRequest(string url, string sensor1, int sensor1Data, string sensor2, int sensor2Data)
{
string payload = "{\"" + sensor1 + "\": " + sensor1Data + ",\"" + sensor2 + "\": " + sensor2Data + "}";
Debug.Print("JSON String is " + payload);
var request = (HttpWebRequest)WebRequest.Create(url);
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
public int ReceiveWebRequest(string url, string controlVar)
{
string requestUrl = url + controlVar + "/" + "lv";
Debug.Print("Making a Get Request to:- " + requestUrl);
//"http://things.ubidots.com/api/v1.6/devices/testDevice/relay1button/lv";
var request = (HttpWebRequest)WebRequest.Create(requestUrl);
request.Method = "GET";
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
var httpResponse = (HttpWebResponse)request.GetResponse();
int dataReceived = 0;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
string resultData = result;
Debug.Print("Relay Data:- " + resultData + " length:- " + resultData.Length);
double temp = double.Parse(resultData);
dataReceived = (int)temp;
}
return dataReceived;
}
public void MakeWebRequest(string url)
{
var value = 25;
string sensor = "temperature";
string payload = "{\"" + sensor + "\": " + value + "}";
Debug.Print("JSON String is " + payload);
//string payload = "{\"temperature\": 56, \"luminosity\": {\"value\":16}}";
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
//Creating a byte array for our payload for length calculation
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
protected bool CheckIPAddress(NetworkInterface net)
{
int timeout = 10000; // timeout, in milliseconds to wait for an IP. 10,000 = 10 seconds
// check to see if the IP address is empty (0.0.0.0). IPAddress.Any is 0.0.0.0.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("No IP Address");
if (net.IsDhcpEnabled)
{
Debug.Print("DHCP is enabled, attempting to get an IP Address");
// ask for an IP address from DHCP [note this is a static, not sure which network interface it would act on]
int sleepInterval = 10;
int maxIntervalCount = timeout / sleepInterval;
int count = 0;
while (IPAddress.GetDefaultLocalAddress() == IPAddress.Any && count < maxIntervalCount)
{
Debug.Print("Sleep while obtaining an IP");
Thread.Sleep(10);
count++;
};
// if we got here, we either timed out or got an address, so let's find out.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("Failed to get an IP Address in the alotted time.");
return false;
}
Debug.Print("Got IP Address: " + net.IPAddress.ToString());
return true;
//NOTE: this does not work, even though it's on the actual network device. [shrug]
// try to renew the DHCP lease and get a new IP Address
//net.RenewDhcpLease ();
//while (net.IPAddress == "0.0.0.0") {
// Thread.Sleep (10);
//}
}
else
{
Debug.Print("DHCP is not enabled, and no IP address is configured, bailing out.");
return false;
}
}
else
{
Debug.Print("Already had IP Address: " + net.IPAddress.ToString());
return true;
}
}
protected void ListNetworkInterfaces()
{
foreach (var net in _interfaces)
{
switch (net.NetworkInterfaceType)
{
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
}
}
protected void ListNetworkInfo(NetworkInterface net)
{
Debug.Print("MAC Address: " + BytesToHexString(net.PhysicalAddress));
Debug.Print("DHCP enabled: " + net.IsDhcpEnabled.ToString());
Debug.Print("Dynamic DNS enabled: " + net.IsDynamicDnsEnabled.ToString());
Debug.Print("IP Address: " + net.IPAddress.ToString());
Debug.Print("Subnet Mask: " + net.SubnetMask.ToString());
Debug.Print("Gateway: " + net.GatewayAddress.ToString());
if (net is Wireless80211)
{
var wifi = net as Wireless80211;
Debug.Print("SSID:" + wifi.Ssid.ToString());
}
}
private static string BytesToHexString(byte[] bytes)
{
string hexString = string.Empty;
// Create a character array for hexidecimal conversion.
const string hexChars = "0123456789ABCDEF";
// Loop through the bytes.
for (byte b = 0; b < bytes.Length; b++)
{
if (b > 0)
hexString += "-";
// Grab the top 4 bits and append the hex equivalent to the return string.
hexString += hexChars[bytes[b] >> 4];
// Mask off the upper 4 bits to get the rest of it.
hexString += hexChars[bytes[b] & 0x0F];
}
return hexString;
}
}
}
Now the main part where the LED Control takes place based on Ubidots "relay1button" widget is inside the main function in class Program. Outside the continous while loop we first intialize the led pin to low or we turn it off. Then inside the while loop you check continuously after every 2500 milliseconds for the last value of the "relay1button" variable which can be changed by clicking on it's widget present in Ubidots Website Dashboard or it's Smartphone application. When you click the "relay1button" widget you either send 1 (i.e. turn on the led) or 0 (i.e. to turn off the led).
led.Write(false); // turn off the LED onboard the Netduino
Debug.Print("Turn off the LED onboard the Netduino");
while (true)
{
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
string controlVariable1 = "relay1button";
int dataReceived = app.ReceiveWebRequest(ubidotsURL, controlVariable1);
Debug.Print("");
Debug.Print("Data Received:- " + dataReceived);
if (dataReceived == 1)
{
Debug.Print("Turn ON the LED onboard the Netduino");
led.Write(true); // turn ON the LED onboard the Netduino
}
else if (dataReceived == 0)
{
Debug.Print("Turn OFF the LED onboard the Netduino");
led.Write(false); // turn OFF the LED onboard the Netduino
}
Thread.Sleep(2500);
}
Relay Controlling using Netduino and Ubidots:-We will be using a Grove Relay module connected to the Netduino using Grove Base shield. You can add as many Relays as you want but since this is a prototype i am using a single relay!
Now let's change this code to control a actual LED Bulb using relay. It's very easy just add a relay to a digital pin i.e D2 here and add following lines:-
First intialize the pin to which relay1 is connected and then let it be initially turned off because we will control it via the Ubidots IoT platform:-
OutputPort relay1 = new OutputPort(Pins.GPIO_PIN_D2, false);
relay1.Write(false); // turn off the relay
Debug.Print("Turning the Relay1 OFF Connected to Pin D2");
Now inside the while(true) loop instead of controlling the on-board led we will be controlling the relay pin.
while (true)
{
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
string controlVariable1 = "relay1button";
int dataReceived = app.ReceiveWebRequest(ubidotsURL, controlVariable1);
Debug.Print("");
Debug.Print("Data Received:- " + dataReceived);
if (dataReceived == 1)
{
relay1.Write(true); // turn on the relay
Debug.Print("Turning the Relay1 ON Connected to Pin D2");
}
else if (dataReceived == 0)
{
relay1.Write(false); // turn off the relay
Debug.Print("Turning the Relay1 OFF Connected to Pin D2");
}
Thread.Sleep(2500);
}
The relay controlling code:-
using System; //For functions like Random number generator
using System.Net; //For http web request, ip address mthods
using System.Text; //For Encoding.UTF8.GetBytes method
using System.IO; //For StreamReader methods
using System.Threading; //For Thread methods like Sleep
using Microsoft.SPOT; //For Serial Debug method
using Microsoft.SPOT.Hardware; //For input/Output functions like OutputPort
using SecretLabs.NETMF.Hardware.Netduino; //For input/output functions like pin definition Pins.ONBOARD_LED
using Microsoft.SPOT.Net.NetworkInformation; //for networkinterface and related methods
//Your project name should always match the below namespace name
namespace UbidotsIntervalUploading
{
public class Program
{
public static void Main()
{
OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
OutputPort relay1 = new OutputPort(Pins.GPIO_PIN_D2, false);
relay1.Write(false); // turn off the relay
Debug.Print("Turning the Relay1 OFF Connected to Pin D2");
//relay1.Write(true); // turn on the relay
led.Write(true); // turn on the LED
Thread.Sleep(1000); // sleep for 1000ms
led.Write(false); // turn off the LED
Thread.Sleep(1000); // sleep for 250ms
led.Write(true); // turn on the LED
Thread.Sleep(1000); // sleep for 1000ms
led.Write(false); // turn off the LED
Thread.Sleep(1000); // sleep for 1000ms
Debug.Print("Ready to Run.....!");
App app = new App();
app.Run();
while (app.IsRunning)
{
led.Write(true); // turn on the LED
Thread.Sleep(250); // sleep for 250ms
led.Write(false); // turn off the LED
Thread.Sleep(250); // sleep for 250ms
}
while (app.ipCheck == false)
{
app.Run();
Thread.Sleep(1000);
}
//led.Write(false); // turn off the LED onboard the Netduino
//Debug.Print("Turn off the LED onboard the Netduino");
while (true)
{
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
string controlVariable1 = "relay1button";
int dataReceived = app.ReceiveWebRequest(ubidotsURL, controlVariable1);
Debug.Print("");
Debug.Print("Data Received:- " + dataReceived);
if (dataReceived == 1)
{
relay1.Write(true); // turn on the relay
Debug.Print("Turning the Relay1 ON Connected to Pin D2");
}
else if (dataReceived == 0)
{
relay1.Write(false); // turn off the relay
Debug.Print("Turning the Relay1 OFF Connected to Pin D2");
}
Thread.Sleep(2500);
}
}
}
public class App
{
NetworkInterface[] _interfaces;
//public bool IsRunning { get; set; }
bool _IsRunning;
public bool IsRunning
{
get { return _IsRunning; }
set { _IsRunning = value; }
}
bool _ipCheck;
public bool ipCheck
{
get { return _ipCheck; }
set { _ipCheck = value; }
}
public void Run()
{
this.IsRunning = true;
Debug.Print("Initializing the networks...");
bool goodToGo = InitializeNetwork();
this.ipCheck = goodToGo;
if (goodToGo)
{
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
MakeWebRequest(ubidotsURL);
}
this.IsRunning = false;
}
protected bool InitializeNetwork()
{
if (Microsoft.SPOT.Hardware.SystemInfo.SystemID.SKU == 3)
{
Debug.Print("Wireless tests run only on Device");
return false;
}
Debug.Print("Getting all the network interfaces.");
_interfaces = NetworkInterface.GetAllNetworkInterfaces();
// debug output
ListNetworkInterfaces();
// loop through each network interface
foreach (var net in _interfaces)
{
// debug out
ListNetworkInfo(net);
switch (net.NetworkInterfaceType)
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
// check for an IP address, try to get one if it's empty
return CheckIPAddress(net);
}
// if we got here, should be false.
return false;
}
public void UploadWebRequest(string url, string sensor1, int sensor1Data, string sensor2, int sensor2Data)
{
string payload = "{\"" + sensor1 + "\": " + sensor1Data + ",\"" + sensor2 + "\": " + sensor2Data + "}";
Debug.Print("JSON String is " + payload);
var request = (HttpWebRequest)WebRequest.Create(url);
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
public int ReceiveWebRequest(string url, string controlVar)
{
string requestUrl = url + controlVar + "/" + "lv";
Debug.Print("Making a Get Request to:- " + requestUrl);
//"http://things.ubidots.com/api/v1.6/devices/testDevice/relay1button/lv";
var request = (HttpWebRequest)WebRequest.Create(requestUrl);
request.Method = "GET";
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
var httpResponse = (HttpWebResponse)request.GetResponse();
int dataReceived = 0;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
string resultData = result;
Debug.Print("Relay Data:- " + resultData + " length:- " + resultData.Length);
double temp = double.Parse(resultData);
dataReceived = (int)temp;
}
return dataReceived;
}
public void MakeWebRequest(string url)
{
var value = 25;
string sensor = "temperature";
string payload = "{\"" + sensor + "\": " + value + "}";
Debug.Print("JSON String is " + payload);
//string payload = "{\"temperature\": 56, \"luminosity\": {\"value\":16}}";
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
//Creating a byte array for our payload for length calculation
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
protected bool CheckIPAddress(NetworkInterface net)
{
int timeout = 10000; // timeout, in milliseconds to wait for an IP. 10,000 = 10 seconds
// check to see if the IP address is empty (0.0.0.0). IPAddress.Any is 0.0.0.0.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("No IP Address");
if (net.IsDhcpEnabled)
{
Debug.Print("DHCP is enabled, attempting to get an IP Address");
// ask for an IP address from DHCP [note this is a static, not sure which network interface it would act on]
int sleepInterval = 10;
int maxIntervalCount = timeout / sleepInterval;
int count = 0;
while (IPAddress.GetDefaultLocalAddress() == IPAddress.Any && count < maxIntervalCount)
{
Debug.Print("Sleep while obtaining an IP");
Thread.Sleep(10);
count++;
};
// if we got here, we either timed out or got an address, so let's find out.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("Failed to get an IP Address in the alotted time.");
return false;
}
Debug.Print("Got IP Address: " + net.IPAddress.ToString());
return true;
//NOTE: this does not work, even though it's on the actual network device. [shrug]
// try to renew the DHCP lease and get a new IP Address
//net.RenewDhcpLease ();
//while (net.IPAddress == "0.0.0.0") {
// Thread.Sleep (10);
//}
}
else
{
Debug.Print("DHCP is not enabled, and no IP address is configured, bailing out.");
return false;
}
}
else
{
Debug.Print("Already had IP Address: " + net.IPAddress.ToString());
return true;
}
}
protected void ListNetworkInterfaces()
{
foreach (var net in _interfaces)
{
switch (net.NetworkInterfaceType)
{
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
}
}
protected void ListNetworkInfo(NetworkInterface net)
{
Debug.Print("MAC Address: " + BytesToHexString(net.PhysicalAddress));
Debug.Print("DHCP enabled: " + net.IsDhcpEnabled.ToString());
Debug.Print("Dynamic DNS enabled: " + net.IsDynamicDnsEnabled.ToString());
Debug.Print("IP Address: " + net.IPAddress.ToString());
Debug.Print("Subnet Mask: " + net.SubnetMask.ToString());
Debug.Print("Gateway: " + net.GatewayAddress.ToString());
if (net is Wireless80211)
{
var wifi = net as Wireless80211;
Debug.Print("SSID:" + wifi.Ssid.ToString());
}
}
private static string BytesToHexString(byte[] bytes)
{
string hexString = string.Empty;
// Create a character array for hexidecimal conversion.
const string hexChars = "0123456789ABCDEF";
// Loop through the bytes.
for (byte b = 0; b < bytes.Length; b++)
{
if (b > 0)
hexString += "-";
// Grab the top 4 bits and append the hex equivalent to the return string.
hexString += hexChars[bytes[b] >> 4];
// Mask off the upper 4 bits to get the rest of it.
hexString += hexChars[bytes[b] & 0x0F];
}
return hexString;
}
}
}
Now you should connect the relay to digital pin D2 and hear a click sound whenever you turn it ON using the Ubidots website or App. Connect anything you want to control to this relay and voila your home automation project is ready. ;)
Like control your coffee pot or toaster or even your Air Conditioner or Fan or Room Lights or Solenoid Lock (Door Lock) or etc. the list will never end. It's upto you what you want control!
"May the force be with you!" :)
Analog Sensors Interfacing with Netduino:-Now let's connect the Grove LDR and Grove Air Quality Sensors to the Netduino using Grove Base shield. The popular map function available in Arduino is not present in Netduino Visual Studio IDE. We have to write a map function which will convert the analog values of LDR sensor to 0 to 100% for human understandable form of light intensity.
using System.Threading;
using Microsoft.SPOT;
using SecretLabs.NETMF.Hardware.Netduino;
namespace NetduinoAnalogExample
{
public class Program
{
public static void Main()
{
// write your code here
var ldrSensor = new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0);
var airQualitySensor = new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A1);
//ldrSensor.SetRange(0, 100);
while (true)
{
int ldrValue = ldrSensor.Read();
int ldrMax = 670;
int ldrMin = 0;
Debug.Print("LDR Sensor Reading: " + ldrValue.ToString());
int ldrPercent = analogMap(ldrValue, ldrMin, ldrMax, 0, 100);
Debug.Print("LDR Sensor Percent: " + ldrPercent.ToString());
int airQualityValue = airQualitySensor.Read();
Debug.Print("Air Quality Sensor Reading: " + airQualityValue.ToString());
if (airQualityValue > 700)
{
Debug.Print("High Air Pollution");
}
else if ((airQualityValue > 300) && (airQualityValue < 700))
{
Debug.Print("Low Air Pollution");
}
else
{
Debug.Print("Air is Fresh!!");
}
Debug.Print("");
Debug.Print("");
Thread.Sleep(2500);
}
}
static int analogMap(int x, int in_min, int in_max, int out_min, int out_max)
{
/* Map an analog value (i.e variable x which has current values from in_min to in_max) to a specific range (from out_min to out_max) */
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
}
}
References you require for the analog read functionality on Netduino:-
Serial Debug Output is:-
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
LDR Sensor Reading: 171
LDR Sensor Percent: 25
Air Quality Sensor Reading: 142
Air is Fresh!!
The thread '<No Name>' (0x4) has exited with code 0 (0x0).
LDR Sensor Reading: 175
LDR Sensor Percent: 26
Air Quality Sensor Reading: 140
Air is Fresh!!
I2C sensor Interfacing with the Netduino:-The Grove I2C TH02 Temperature and Humidity sensor will be interfaced with the Netduino board.
I used below Arduino code as reference to make C# code for Netduino!
#include <Wire.h>
// TH02 I2C address is 0x40(64)
#define Addr 0x40
double cTemp = 0.0, humidity = 0.0;
void setup()
{
// Initialise I2C communication as MASTER
Wire.begin();
// Initialise serial communication, set baud rate = 9600
Serial.begin(9600);
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Stop I2C transmission
Wire.endTransmission();
delay(300);
}
void loop()
{
unsigned int data[3];
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select configuration register
Wire.write(0x03);
// Normal mode enabled, Temperature
Wire.write(0x11);
// Stop I2C transmission
Wire.endTransmission();
delay(500);
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write(0x00);
// Stop I2C transmission
Wire.endTransmission();
// Request 3 bytes of data
Wire.requestFrom(Addr, 3);
// Read 3 bytes of data
// Status, temp msb, temp lsb
if(Wire.available() == 3)
{
data[0] = Wire.read();
data[1] = Wire.read();
data[2] = Wire.read();
}
// Convert the data to 14-bits
float temp = ((data[1] * 256.0) + (data[2] & 0xFC)) / 4;
float cTemp = (temp / 32.0) - 50.0;
float fTemp = cTemp * 1.8 + 32 ;
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select configuration register
Wire.write(0x03);
// Normal mode enabled, Relative Humidity
Wire.write(0x01);
// Stop I2C transmission
Wire.endTransmission();
delay(500);
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write(0x00);
// Stop I2C transmission
Wire.endTransmission();
// Request 3 bytes of data
Wire.requestFrom(Addr, 3);
// Read 3 bytes of data
// Status, humidity msb, humidity lsb
if(Wire.available() == 3)
{
data[0] = Wire.read();
data[1] = Wire.read();
data[2] = Wire.read();
}
// Convert the data to 12-bits
float hum = ((((data[1] * 256.0) + (data[2] & 0xF0)) / 16) / 16 ) - 24;
float humidity = (hum * 1.0 - (((hum * 1.0 * hum * 1.0) * (-0.00393)) + (hum * 0.4008) - 4.7844));
humidity = humidity + ((cTemp - 30) * ((humidity * 0.00237) + 0.1937));
Serial.print("Temperature:- ");
Serial.println(cTemp);
Serial.print("Humidity:- ");
Serial.println(humidity);
delay(2000);
}
The code:-
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;
namespace I2C_TH02_Sensor_Example
{
public class Program
{
public static string ByteToHex(byte val)
{
const string hex = "0123456789abcdef";
return (new string(new char[] { '0', 'x', hex[(val & 0xf0) >> 4], hex[val & 0x0f] }));
}
public static void Main()
{
double cTemp = 0;
double fTemp = 0;
double humidity = 0;
// TH02 I2C address is 0x40(64)
// Create a new I2C device for the TH02 on address 0x40 with the clock running at 100 kHz
const int TransactionTimeout = 1000; // ms
const byte ClockRateKHz = 100;
I2CDevice th02Sensor = new I2CDevice(new I2CDevice.Configuration(0x40, 100));
//Single transaction of I2C writing two bytes of Data to the slave device
I2CDevice.I2CTransaction[] tempConfig = new I2CDevice.I2CTransaction[1];
// Select configuration register 0x03
// Normal mode enabled, Temperature 0x11
byte[] configurationRegister1 = new byte[2] { 0x03, 0x11 };
tempConfig[0] = I2CDevice.CreateWriteTransaction(configurationRegister1);
int written = 0;
written = th02Sensor.Execute(tempConfig, TransactionTimeout);
// make sure the data was sent
if (written != 0)
{
Debug.Print("Temp Config Data Written to device. " + written);
}
else
{
Debug.Print("Temp Config Could not write to device. " + written);
written = th02Sensor.Execute(tempConfig, TransactionTimeout);
Debug.Print("Temp Config Data Written to device. " + written);
}
Thread.Sleep(1000);
//Single transaction of I2C writing two bytes of Data to the slave device
I2CDevice.I2CTransaction[] humConfig = new I2CDevice.I2CTransaction[1];
// Select configuration register 0x03
// Normal mode enabled, Relative Humidity 0x01
byte[] configurationRegister2 = new byte[2] { 0x03, 0x01 };
humConfig[0] = I2CDevice.CreateWriteTransaction(configurationRegister2);
written = 0;
written = th02Sensor.Execute(humConfig, TransactionTimeout);
// make sure the data was sent
if (written != 0)
{
Debug.Print("Hum Config Data Written to device. " + written);
}
else
{
Debug.Print("Hum Config Could not write to device. " + written);
written = th02Sensor.Execute(humConfig, TransactionTimeout);
Debug.Print("Hum Config Data Written to device. " + written);
}
Thread.Sleep(1000);
//Two transactions of I2C writing one byte of Data to the slave device and then reading the sensor data
I2CDevice.I2CTransaction[] sensorReading = new I2CDevice.I2CTransaction[2];
// Select data register
byte[] dataRegister = { 0x00 };
sensorReading[0] = I2CDevice.CreateWriteTransaction(dataRegister);
byte[] sensorData = new byte[3];
sensorReading[1] = I2CDevice.CreateReadTransaction(sensorData);
while (true)
{
written = th02Sensor.Execute(tempConfig, TransactionTimeout);
Thread.Sleep(500);
// make sure the data was sent
if (written != 0)
{
Debug.Print("Temp Config Data Written to device. " + written);
// Read the temperature.
int bytesRead = th02Sensor.Execute(sensorReading, TransactionTimeout);
// make sure the data was read
if (bytesRead != 0)
{
Debug.Print(bytesRead + " bytes of Data read from device.");
Debug.Print("Bytes of Data Read:- " + bytesRead);
Debug.Print("Temperature bytes data: " + sensorData[0] + ", " + sensorData[1] + ", " + sensorData[2]);
Debug.Print("Temperature bytes data: " + ByteToHex(sensorData[0]) + ", " + ByteToHex(sensorData[1]) + ", " + ByteToHex(sensorData[2]));
// Convert the data to 14-bits
double temp = ((sensorData[1] * 256.0) + (sensorData[2] & 0xFC)) / 4;
cTemp = (temp / 32.0) - 50.0;
fTemp = cTemp * 1.8 + 32;
// Display the readings in the debug window and pause before repeating.
Debug.Print(cTemp.ToString() + " C / " + fTemp.ToString() + " F");
Thread.Sleep(500);
}
else
{
Debug.Print("Temp sensor data Could not read from device. " + bytesRead);
}
}
else
{
Debug.Print("Tem Config Could not Write to device. " + written);
}
written = th02Sensor.Execute(humConfig, TransactionTimeout);
Thread.Sleep(500);
// make sure the data was sent
if (written != 0)
{
Debug.Print("Hum Config Data Written to device. " + written);
// Read the temperature.
int bytesRead = th02Sensor.Execute(sensorReading, TransactionTimeout);
// make sure the data was read
if (bytesRead != 0)
{
Debug.Print(bytesRead + " bytes of Data read from device.");
Debug.Print("Bytes of Data Read:- " + bytesRead);
Debug.Print("Humidity bytes data: " + sensorData[0] + ", " + sensorData[1] + ", " + sensorData[2]);
Debug.Print("Humidity bytes data: " + ByteToHex(sensorData[0]) + ", " + ByteToHex(sensorData[1]) + ", " + ByteToHex(sensorData[2]));
// Convert the data to 12-bits
double hum = ((((sensorData[1] * 256.0) + (sensorData[2] & 0xF0)) / 16) / 16) - 24;
humidity = (hum * 1.0 - (((hum * 1.0 * hum * 1.0) * (-0.00393)) + (hum * 0.4008) - 4.7844));
humidity = humidity + ((cTemp - 30) * ((humidity * 0.00237) + 0.1937));
// Display the readings in the debug window and pause before repeating.
Debug.Print(humidity.ToString() + " % Humidity ");
Thread.Sleep(500);
}
else
{
Debug.Print("Hum sensor data Could not read from device. " + bytesRead);
}
}
else
{
Debug.Print("Hum Config Could not Write to device. " + written);
}
}
}
}
}
All the Grove sensors and modules we connected works fine when provided power supply of 3.3V from Grove Base shield except the Grove I2C Temperature and Humidity Sensor which is working fine at 5V.
The serial debug output:-
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Temp Config Could not write to device. 0
Temp Config Data Written to device. 2
Hum Config Data Written to device. 2
The thread '<No Name>' (0x4) has exited with code 0 (0x0).
Temp Config Data Written to device. 2
4 bytes of Data read from device.
Bytes of Data Read:- 4
Temperature bytes data: 0, 39, 164
Temperature bytes data: 0x00, 0x27, 0xa4
29.28125 C / 84.706250000000011 F
Hum Config Data Written to device. 2
4 bytes of Data read from device.
Bytes of Data Read:- 4
Humidity bytes data: 0, 116, 48
Humidity bytes data: 0x00, 0x74, 0x30
93.124032081207105 % Humidity
The sensor seems to work fine when provided 5V via Grove base shield but not at 3.3V. At 3.3V it returns null data.
The serial debug for which is:
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Temp Config Could not write to device. 0
The thread '<No Name>' (0x4) has exited with code 0 (0x0).
Temp Config Data Written to device. 0
Hum Config Could not write to device. 0
Hum Config Data Written to device. 0
I am facing this problem i don't know the exact reason since the sensor working voltage is specified as 3.3V to 5V. As digital pins of Netduino are 5V tolerant i can keep the Grove base shield voltage switch towards 5V side but the problem lies with Analog pins which are not 5V tolerant and hence can get damaged so i was successful in interfacing the sensor to Netduino but right now will not incorporate it in the final demo.
Final Code:-The final code with Grove Light Sensor, Grove Air Quality Sensor and Grove Relay module connected to the Netduino board via the Grove Base Shield:-
using System; //For functions like Random number generator
using System.Net; //For http web request, ip address mthods
using System.Text; //For Encoding.UTF8.GetBytes method
using System.IO; //For StreamReader methods
using System.Threading; //For Thread methods like Sleep
using Microsoft.SPOT; //For Serial Debug method
using Microsoft.SPOT.Hardware; //For input/Output functions like OutputPort
using SecretLabs.NETMF.Hardware.Netduino; //For input/output functions like pin definition Pins.ONBOARD_LED
using Microsoft.SPOT.Net.NetworkInformation; //for networkinterface and related methods
//Your project name should always match the below namespace name
namespace UbidotsIntervalUploading
{
public class Program
{
static int analogMap(int x, int in_min, int in_max, int out_min, int out_max)
{
/* Map an analog value (i.e variable x which has current values from in_min to in_max) to a specific range (from out_min to out_max) */
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
public static void Main()
{
OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
OutputPort relay1 = new OutputPort(Pins.GPIO_PIN_D2, false);
relay1.Write(false); // turn off the relay
Debug.Print("Turning the Relay1 OFF Connected to Pin D2");
var ldrSensor = new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0);
var airQualitySensor = new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A1);
//relay1.Write(true); // turn on the relay
led.Write(true); // turn on the LED
Thread.Sleep(1000); // sleep for 1000ms
led.Write(false); // turn off the LED
Thread.Sleep(1000); // sleep for 250ms
led.Write(true); // turn on the LED
Thread.Sleep(1000); // sleep for 1000ms
led.Write(false); // turn off the LED
Thread.Sleep(1000); // sleep for 1000ms
Debug.Print("Ready to Run.....!");
App app = new App();
app.Run();
while (app.IsRunning)
{
led.Write(true); // turn on the LED
Thread.Sleep(250); // sleep for 250ms
led.Write(false); // turn off the LED
Thread.Sleep(250); // sleep for 250ms
}
while (app.ipCheck == false)
{
app.Run();
Thread.Sleep(1000);
}
//led.Write(false); // turn off the LED onboard the Netduino
//Debug.Print("Turn off the LED onboard the Netduino");
while (true)
{
string deviceLabel = "netduino_smart_home";
string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
ubidotsURL = ubidotsURL + deviceLabel + "/";
//app.MakeWebRequest(ubidotsURL);
int ldrValue = ldrSensor.Read();
int ldrMax = 670;
int ldrMin = 0;
Debug.Print("LDR Sensor Reading: " + ldrValue.ToString());
int ldrPercent = analogMap(ldrValue, ldrMin, ldrMax, 0, 100);
Debug.Print("LDR Sensor Percent: " + ldrPercent.ToString());
int airQualityValue = airQualitySensor.Read();
Debug.Print("Air Quality Sensor Reading: " + airQualityValue.ToString());
if (airQualityValue > 700)
{
Debug.Print("High Air Pollution");
}
else if ((airQualityValue > 300) && (airQualityValue < 700))
{
Debug.Print("Low Air Pollution");
}
else
{
Debug.Print("Air is Fresh!!");
}
string sensor1Label = "lightLevel";
int sensor1Data = ldrPercent;
string sensor2Label = "airQuality";
int sensor2Data = airQualityValue;
app.UploadWebRequest(ubidotsURL, sensor1Label, sensor1Data, sensor2Label, sensor2Data);
string controlVariable1 = "relay1button";
int dataReceived = app.ReceiveWebRequest(ubidotsURL, controlVariable1);
Debug.Print("");
Debug.Print("Data Received:- " + dataReceived);
if (dataReceived == 1)
{
relay1.Write(true); // turn on the relay
Debug.Print("Turning the Relay1 ON Connected to Pin D2");
}
else if (dataReceived == 0)
{
relay1.Write(false); // turn off the relay
Debug.Print("Turning the Relay1 OFF Connected to Pin D2");
}
Thread.Sleep(2500);
}
}
}
public class App
{
NetworkInterface[] _interfaces;
//public bool IsRunning { get; set; }
bool _IsRunning;
public bool IsRunning
{
get { return _IsRunning; }
set { _IsRunning = value; }
}
bool _ipCheck;
public bool ipCheck
{
get { return _ipCheck; }
set { _ipCheck = value; }
}
public void Run()
{
this.IsRunning = true;
Debug.Print("Initializing the networks...");
bool goodToGo = InitializeNetwork();
this.ipCheck = goodToGo;
if (goodToGo)
{
Debug.Print("The Netowrk Connection is good to go!");
//string deviceLabel = "netduino_smart_home";
//string ubidotsURL = "http://things.ubidots.com/api/v1.6/devices/";
//ubidotsURL = ubidotsURL + deviceLabel + "/";
//MakeWebRequest(ubidotsURL);
}
this.IsRunning = false;
}
protected bool InitializeNetwork()
{
if (Microsoft.SPOT.Hardware.SystemInfo.SystemID.SKU == 3)
{
Debug.Print("Wireless tests run only on Device");
return false;
}
Debug.Print("Getting all the network interfaces.");
_interfaces = NetworkInterface.GetAllNetworkInterfaces();
// debug output
ListNetworkInterfaces();
// loop through each network interface
foreach (var net in _interfaces)
{
// debug out
ListNetworkInfo(net);
switch (net.NetworkInterfaceType)
{
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
// check for an IP address, try to get one if it's empty
return CheckIPAddress(net);
}
// if we got here, should be false.
return false;
}
public void UploadWebRequest(string url, string sensor1, int sensor1Data, string sensor2, int sensor2Data)
{
string payload = "{\"" + sensor1 + "\": " + sensor1Data + ",\"" + sensor2 + "\": " + sensor2Data + "}";
Debug.Print("JSON String is " + payload);
var request = (HttpWebRequest)WebRequest.Create(url);
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
public int ReceiveWebRequest(string url, string controlVar)
{
string requestUrl = url + controlVar + "/" + "lv";
Debug.Print("Making a Get Request to:- " + requestUrl);
//"http://things.ubidots.com/api/v1.6/devices/testDevice/relay1button/lv";
var request = (HttpWebRequest)WebRequest.Create(requestUrl);
request.Method = "GET";
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
var httpResponse = (HttpWebResponse)request.GetResponse();
int dataReceived = 0;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
string resultData = result;
Debug.Print("Relay Data:- " + resultData + " length:- " + resultData.Length);
double temp = double.Parse(resultData);
dataReceived = (int)temp;
}
return dataReceived;
}
public void MakeWebRequest(string url)
{
var value = 25;
string sensor = "temperature";
string payload = "{\"" + sensor + "\": " + value + "}";
Debug.Print("JSON String is " + payload);
//string payload = "{\"temperature\": 56, \"luminosity\": {\"value\":16}}";
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
//Creating a byte array for our payload for length calculation
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
request.Headers.Add("x-auth-token", "A1E-4gstNUeAYFJ0oPFfSZuPnNbjcPkDcO");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//Debug.Print("This is what we got from " + url + ": " + result);
Debug.Print("Response:- " + result);
}
}
protected bool CheckIPAddress(NetworkInterface net)
{
int timeout = 10000; // timeout, in milliseconds to wait for an IP. 10,000 = 10 seconds
// check to see if the IP address is empty (0.0.0.0). IPAddress.Any is 0.0.0.0.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("No IP Address");
if (net.IsDhcpEnabled)
{
Debug.Print("DHCP is enabled, attempting to get an IP Address");
// ask for an IP address from DHCP [note this is a static, not sure which network interface it would act on]
int sleepInterval = 10;
int maxIntervalCount = timeout / sleepInterval;
int count = 0;
while (IPAddress.GetDefaultLocalAddress() == IPAddress.Any && count < maxIntervalCount)
{
Debug.Print("Sleep while obtaining an IP");
Thread.Sleep(10);
count++;
};
// if we got here, we either timed out or got an address, so let's find out.
if (net.IPAddress == IPAddress.Any.ToString())
{
Debug.Print("Failed to get an IP Address in the alotted time.");
return false;
}
Debug.Print("Got IP Address: " + net.IPAddress.ToString());
return true;
//NOTE: this does not work, even though it's on the actual network device. [shrug]
// try to renew the DHCP lease and get a new IP Address
//net.RenewDhcpLease ();
//while (net.IPAddress == "0.0.0.0") {
// Thread.Sleep (10);
//}
}
else
{
Debug.Print("DHCP is not enabled, and no IP address is configured, bailing out.");
return false;
}
}
else
{
Debug.Print("Already had IP Address: " + net.IPAddress.ToString());
return true;
}
}
protected void ListNetworkInterfaces()
{
foreach (var net in _interfaces)
{
switch (net.NetworkInterfaceType)
{
case (NetworkInterfaceType.Ethernet):
Debug.Print("Found Ethernet Interface");
break;
case (NetworkInterfaceType.Wireless80211):
Debug.Print("Found 802.11 WiFi Interface");
break;
case (NetworkInterfaceType.Unknown):
Debug.Print("Found Unknown Interface");
break;
}
}
}
protected void ListNetworkInfo(NetworkInterface net)
{
Debug.Print("MAC Address: " + BytesToHexString(net.PhysicalAddress));
Debug.Print("DHCP enabled: " + net.IsDhcpEnabled.ToString());
Debug.Print("Dynamic DNS enabled: " + net.IsDynamicDnsEnabled.ToString());
Debug.Print("IP Address: " + net.IPAddress.ToString());
Debug.Print("Subnet Mask: " + net.SubnetMask.ToString());
Debug.Print("Gateway: " + net.GatewayAddress.ToString());
if (net is Wireless80211)
{
var wifi = net as Wireless80211;
Debug.Print("SSID:" + wifi.Ssid.ToString());
}
}
private static string BytesToHexString(byte[] bytes)
{
string hexString = string.Empty;
// Create a character array for hexidecimal conversion.
const string hexChars = "0123456789ABCDEF";
// Loop through the bytes.
for (byte b = 0; b < bytes.Length; b++)
{
if (b > 0)
hexString += "-";
// Grab the top 4 bits and append the hex equivalent to the return string.
hexString += hexChars[bytes[b] >> 4];
// Mask off the upper 4 bits to get the rest of it.
hexString += hexChars[bytes[b] & 0x0F];
}
return hexString;
}
}
}
The serial debug for which is:-
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Turning the Relay1 OFF Connected to Pin D2
The thread '<No Name>' (0x4) has exited with code 0 (0x0).
Ready to Run.....!
Initializing the networks...
Getting all the network interfaces.
Found 802.11 WiFi Interface
MAC Address: 60-D7-E3-A0-04-02
DHCP enabled: True
Dynamic DNS enabled: False
IP Address: 192.168.1.101
Subnet Mask: 255.255.255.0
Gateway: 192.168.1.1
SSID:LittleHeart
Found 802.11 WiFi Interface
Already had IP Address: 192.168.1.101
The Netowrk Connection is good to go!
LDR Sensor Reading: 226
LDR Sensor Percent: 33
Air Quality Sensor Reading: 100
Air is Fresh!!
JSON String is {"lightLevel": 33,"airQuality": 100}
Response:- {"lightlevel": [{"status_code": 201}], "airquality": [{"status_code": 201}]}
Making a Get Request to:- http://things.ubidots.com/api/v1.6/devices/netduino_smart_home/relay1button/lv
Relay Data:- 0.0 length:- 3
Data Received:- 0
Turning the Relay1 OFF Connected to Pin D2
The thread '<No Name>' (0x7) has exited with code 0 (0x0).
LDR Sensor Reading: 198
LDR Sensor Percent: 29
Air Quality Sensor Reading: 99
Air is Fresh!!
JSON String is {"lightLevel": 29,"airQuality": 99}
Response:- {"lightlevel": [{"status_code": 201}], "airquality": [{"status_code": 201}]}
Making a Get Request to:- http://things.ubidots.com/api/v1.6/devices/netduino_smart_home/relay1button/lv
Relay Data:- 1.0 length:- 3
Data Received:- 1
Turning the Relay1 ON Connected to Pin D2
LDR Sensor Reading: 171
LDR Sensor Percent: 25
Air Quality Sensor Reading: 97
Air is Fresh!!
JSON String is {"lightLevel": 25,"airQuality": 97}
The thread '<No Name>' (0x8) has exited with code 0 (0x0).
The thread '<No Name>' (0x9) has exited with code 0 (0x0).
The thread '<No Name>' (0xa) has exited with code 0 (0x0).
Response:- {"lightlevel": [{"status_code": 201}], "airquality": [{"status_code": 201}]}
Making a Get Request to:- http://things.ubidots.com/api/v1.6/devices/netduino_smart_home/relay1button/lv
Relay Data:- 1.0 length:- 3
Final Code References you will require to add in your project:-
Ubidots Dashboard:-
Variables in the netduino_smart_home Device in Ubidots account:-
Dashboard Link (Shareable link)
Working Demo of the Final Code:-
Future Considerations:-First to make sure to have a 3.3V working Digital (I2C most likely) Temperature and Humidity sensor with all the sensors and modules i have connected with Netduino.
Add a different bunch of sensors to make my home a little more smart like Grove PIR sensor, Grove Sound Sensor, Grove Capacitive Touch Sensor, etc.
Also adding a RGB led to denote the data uploading/recieving part and also whether it connected to the internet or not.
Make the code more efficient like using timer function to call for reading the sensors and uploading it at periodical intervals, etc.
Hey guys i tried my best to make you understand how i made my smart home prototype and i hope you understood everything what i have presented here. There was so much i want to explain but it seems this page will not end. It was my first time working with Netduino and with Visual Studio; faced a lot of problems but at last the project was completed and i am happy with the result.
I hope you liked my project and Happy Hacking!
Comments