Click here to Skip to main content
Click here to Skip to main content

Home Automation with Netduino and Kinect

By , 12 Mar 2012
 

Introduction

Home automation has been an interest of mine for a long time. There is a bunch of bad technology in the marketplace and the products are too expensive so I decided to build my own. I started out with the Arduino microcontroller which was really fun but the code quickly became hard to maintain because it was not object oriented. Additionally it could not do multithreading or real debugging with breakpoints and such. I refactored the code for C# and the .NET Micro Framework. I choose the netduino plus, http://www.netduino.com/netduinoplus/specs.htm, for the microcontroller which has a built in Ethernet adapter for network communication.

Please be sure to also see the sequel to this article: Using jQuery Mobile with MVC and Netduino for Home Automation

The figure below shows an early prototype of the project.

NetduinoHomeAutomation/LogicalDan_001.jpg

Netduino Controlled Squirt Gun

The first project that I built was a servo controlled squirt gun for the pool. The code that I wrote for the netduino controls the servos to spray the gun in different patterns in the pool. I then built a Windows Phone 7 interface to aim the servos to the position on the screen where you touch. I used IIS live smooth streaming to stream video to the phone so you could remotely nail the kids in the pool from anywhere. I had mixed results with the video piece and at some point I need to spend more time perfecting and reducing the buffering time to make it more real time.

NetduinoHomeAutomation/LogicalDan_002.jpg NetduinoHomeAutomation/LogicalDan_003.jpg

Garden

My next project was to control the irrigation of the garden. My code schedules the times to water the garden and controls the duration of the watering.

NetduinoHomeAutomation/LogicalDan_004.jpg

Kinect

One of my colleagues in the office started doing projects with the Microsoft Kinect which has a rich SDK complete with drivers, APIs and plenty of good sample code. The Kinect has a bunch of sensors including a RGB camera, depth sensor and multi-array microphone. With a Kinect, you are the controller! I got the idea of using the Kinect for the controller of the squirt gun in the pool. You can now aim the gun by pointing to where you want it to shoot. The trigger is controlled by bending your other arm so that the hand is above the elbow joint. Plugging in the Kinect for the controller was really simple because of the rich Kinect API and because I had already written the back end tiers to communicate with the netduino microcontroller.

NetduinoHomeAutomation/VideoSquirtGun.JPG
Watch this video of the Squirt Gun

Speech Recognition on the Kinect

One of the other features on the Kinect is the multi-array microphone with speech recognition. I played around with speech commands to control the squirt gun and to open the garage.

Watch this video of Simon Says Kinect

Android Garage Door Opener

I wanted to learn a little about Android development so I wrote a native Android app to call a REST web service (WCF) that talks to the netduino to open the garage.

Putting it all Together

The image below shows the communication between the components. NetduinoHomeAutomation/LogicalDan_005.jpg

The image below shows the devices that the Netduino controls. The fireplace project is in progress and I just started working on it.

NetduinoHomeAutomation/LogicalDan_006.jpg

NetduinoHomeAutomation/VideoAll.JPG
Watch this video to see how it all comes together

Ethernet Communication

The Ethernet communication with the netduino was the hardest part of the project.

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using Microsoft.SPOT.Net.NetworkInformation;
using System.Threading;

namespace Netduino.Controller
{
    public delegate void MessageEventHandler(string Message);

    class EthernetCommunication
    {
        #region Private Variables
        private string _hostAddress = null;
        private int _port = 80;
        private string _netduinoStaticIPAddress = null;
        private string _subnetMask = null;
        private string _gatewayAddress = null;
        private Thread _listeningThread;
        private Socket _clientSocket = null;
        private static EthernetCommunication _ethernetCommunication;
        #endregion

        #region Constructors
        //This keeps other classes from creating an instance
        private EthernetCommunication()
        {
        }
        #endregion

        #region Public Properties
        public string HostAddress
        {
            set { _hostAddress = value; }
            get { return _hostAddress; }
        }
        public int Port
        {
            set { _port = value; }
            get { return _port; }
        }
        public string NetduinoStaticIPAddress
        {
            set 
            { 
                _netduinoStaticIPAddress = value;
                SetNetduinoStaticIPConfiguration();
            }
            get { return _netduinoStaticIPAddress; }
        }
        public string SubnetMask
        {
            set
            {
                _subnetMask = value;
                SetNetduinoStaticIPConfiguration();
            }
            get { return _subnetMask; }
        }
        public string GatewayAddress
        {
            set 
            {
                _gatewayAddress = value;
                SetNetduinoStaticIPConfiguration();
            }
            get { return _gatewayAddress; }
        }
        #endregion

        #region Events
        public static event MessageEventHandler EventHandlerMessageReceived;
        #endregion

        #region Public Methods
        
        private void StartListening()
        {
            _listeningThread = new Thread(new ThreadStart(ReceiveSocketsInListeningThread));
            _listeningThread.Start();
        }

        private void InitializeConfiguration()
        {
            if (_netduinoStaticIPAddress == null)
                throw new Exception("The netduino Static IP Address nust be set!");

            if (_subnetMask == null)
                throw new Exception("The Subnet Mask must be set!");

            if (_gatewayAddress == null)
                throw new Exception("The Gateway address must be set.");

            SetNetduinoStaticIPConfiguration();
            NetworkInterface networkInterface = NetworkInterface.GetAllNetworkInterfaces()[0];

            if (_netduinoStaticIPAddress != networkInterface.IPAddress)
                throw new Exception("Problem setting the static IP.");

            if (_subnetMask != networkInterface.SubnetMask)
                throw new Exception("Problem setting the subnet mask.");

            if (_gatewayAddress != networkInterface.GatewayAddress)
                throw new Exception("Problem setting the gateway address.");
        }
        #endregion

        #region Public Static Methods
        public static EthernetCommunication GetInstance()
        {
            if (_ethernetCommunication == null)
            {
                _ethernetCommunication = new EthernetCommunication();
                _ethernetCommunication.HostAddress = Config.HostAddress;
                _ethernetCommunication.Port = Config.Port;
                _ethernetCommunication.NetduinoStaticIPAddress = Config.NetduinoStaticIPAddress;
                _ethernetCommunication.SubnetMask = Config.SubnetMask;
                _ethernetCommunication.GatewayAddress = Config.GatewayAddress;
                _ethernetCommunication.InitializeConfiguration();
                _ethernetCommunication.StartListening();
            }
            return _ethernetCommunication;
        }

        public static void SendMessage(string message)
        {
            GetInstance().SendEthernetMessage(message);
        }
        #endregion

        #region Private Methods
        private bool IsSocketConnected(Socket socket)
        {
            bool connectionNotClosedResetOrTerminated = !socket.Poll(1000, SelectMode.SelectRead);
            bool socketHasDataAvailableToRead = (socket.Available != 0);
            return (connectionNotClosedResetOrTerminated || socketHasDataAvailableToRead);
        }

        private void ReceiveSocketsInListeningThread()
        {
            string receiveMessage = "";
            bool exitProgram = false;

            using (System.Net.Sockets.Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                socket.Bind(new IPEndPoint(IPAddress.Any, _port));
                socket.Listen(10);

                while (!exitProgram)
                {
                    Debug.Print("Waiting for connection...");
                    _clientSocket = socket.Accept();  //This call is "blocking" and will will wait for a connection, which also means the thread hangs around
                    Debug.Print( "Connection Accepted!");

                    using (_clientSocket)
                    {
                        while (IsSocketConnected(_clientSocket))
                        {
                            int availablebytes = _clientSocket.Available;
                            byte[] buffer = new byte[availablebytes];
                            _clientSocket.Receive(buffer);
                            if (buffer.Length > 0)
                            {
                                receiveMessage = new string(Encoding.UTF8.GetChars(buffer));
                                RaiseMessageReceivedEvent(receiveMessage);
                                if (receiveMessage.ToUpper() == "EXIT")
                                {
                                    exitProgram = true;
                                }
                            }
                            
                        }
                    }
                }
            }
        }

        private void RaiseMessageReceivedEvent(string message)
        {
            // Event will be null if there are no subscribers
            if (EventHandlerMessageReceived != null)
            {
                EventHandlerMessageReceived(message);
            }
        }

        private void SetNetduinoStaticIPConfiguration()
        {
            //Exit if not all of the configuration properties are set
            if (_netduinoStaticIPAddress == null || _subnetMask == null || _gatewayAddress == null)
                return;

            NetworkInterface networkInterface = NetworkInterface.GetAllNetworkInterfaces()[0];

            bool _ipAddressAlreadySet = _netduinoStaticIPAddress == networkInterface.IPAddress;
            bool _subnetMaskAlreadySet = _subnetMask == networkInterface.SubnetMask;
            bool _gatewayAlreadySet = _gatewayAddress == networkInterface.GatewayAddress;

            if (_ipAddressAlreadySet && _subnetMaskAlreadySet && _gatewayAlreadySet)
                return;

            // Set our IP address to a new value
            // This will be saved in the config sector of the netduino and will survive reboots 
            networkInterface.EnableStaticIP(_netduinoStaticIPAddress, _subnetMask, _gatewayAddress);
        }

        private void SendEthernetMessage(string message)
        {
            if (_hostAddress != null && _port > 0)
            {
                using (System.Net.Sockets.Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                    IPHostEntry entry = Dns.GetHostEntry(_hostAddress);
                    IPAddress address = entry.AddressList[0];
                    IPEndPoint endpoint = new IPEndPoint(address, _port);

                    try
                    {
                        socket.Connect(endpoint);
                        socket.Send(Encoding.UTF8.GetBytes(message));
                        socket.Close();
                        Debug.Print(message);
                    }
                    catch (SocketException se)
                    {
                        Debug.Print("Socket Exception!  Probably no server or bad ip?");
                        Debug.Print(se.StackTrace);
                    }
                }
            }
        }
        #endregion
    }
}

If you want to see an example of how to talk with a desktop application, download the source code and look at the Netduino.Desktop.Messenger project.

Servo Communication

The servos were fun to program. I wrote a servo class that you set the Angle and the Minimum and Maximum degrees. I added the Inverted property to invert the angle because I have an indoor version of the squirt gun that is mounted from the floor while the outdoor version is mounted upside down.

using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;

namespace Netduino.Controller
{
    public class Servo : IDisposable
    {
        #region Private Variables
        private PWM _servo;
        private bool _invertAngle = false;
        private int _degreeMin = Config.DegreeMinDefault;
        private int _degreeMax = Config.DegreeMaxDefault;
        private uint _durationMin = Config.DurationMinDefault;
        private uint _durationMax = Config.DurationMaxDefault;
        private uint _angle = Config.HomeDefaultAngle;
        private uint _period = Config.PeriodDefault;
        #endregion

        #region Constructors
        public Servo(Cpu.Pin pin)
        {
            _servo = new PWM(pin);
            _servo.SetDutyCycle(0);
        }
        #endregion

        #region Public Methods
        public void Dispose()
        {
            DisengageServo();
            _servo.Dispose();
        }

        /// <summary> 
        /// Disengage the servo.  
        /// The servo motor will stop trying to maintain an angle 
        ///  
        public void DisengageServo()
        {
            _servo.SetDutyCycle(0);
        }

        public void EngageServo()
        {
            SetPulse();
        }
        #endregion

        #region Private Methods
        private void SetPulse()
        {
            uint angle = _invertAngle ? 180 - _angle: _angle;
            uint duration = (angle) * (_durationMax - _durationMin) / 180 + _durationMin;
            _servo.SetPulse(period: _period, duration: duration);  
        }
        #endregion

        #region Public Properties
        public int Angle
        {
            set
            {
                if (value > _degreeMax)
                    value = _degreeMax;

                if (value < _degreeMin)
                    value = _degreeMin;

                if (value < 0)
                    value = 0;

                _angle = (uint)value;
                SetPulse();
            }
            get
            {
                return (int)_angle;
            }
        }

        public bool InvertAngle
        {
            set {_invertAngle = value;}
            get { return _invertAngle; }
        }

        public int DegreeMin
        {
            set {_degreeMin  = value;}
            get { return _degreeMin; }
        }

        public int DegreeMax
        {
            set { _degreeMax = value; }
            get { return _degreeMax; }
        }

        public uint durationMin
        {
            set { _durationMin = value; }
            get { return _durationMin; }
        }

        public uint durationMax
        {
            set { _durationMax = value; }
            get { return _durationMax; }
        }

        public uint period
        {
            set { _period = value; }
            get { return _period; }
        }
        #endregion
    }
}

Controlling the Garden

I wrote a library of time commands for the .NET Micro Framework. Note that the .net micro framework is very rich but does not have generics.

using System;
using System.Threading;
using System.Collections;
using Microsoft.SPOT;

namespace Netduino.Controller
{
    public delegate void AlarmCallback();

    class AlarmData
    {
        public int Key { get; set; }
        public ExtendedTimer ExtendedTimer { get; set; }
        public bool RemoveAfterRun { get; set; }
        public AlarmCallback Callback { get; set; }
    }

    class Time
    {
        #region Private Variables
        private static Hashtable _alarmHashtable;
        private static int _key;
        #endregion

        #region Constructors
        //This keeps other classes from creating an instance
        private Time()
        {
        }
        #endregion

        #region Public Static Methods
        public static void SetTime(int year, int month, int day, int hour,int minute, int second, int millisecond )
        {
            DateTime presentTime = new DateTime( year, month, day, hour, minute, second, millisecond);
            Microsoft.SPOT.Hardware.Utility.SetLocalTime(presentTime);
        }

        public static void RunDaily(AlarmCallback alarmCallback, int hour, int minute, int second)
        {
            DateTime alarmTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hour, minute, second, 0);
            
            //If we already missed today then tomorrow is the first day to run
            if(alarmTime<DateTime.Now)
            {
                alarmTime = alarmTime.AddDays(1);
            }

            TimeSpan dailyTimeSpan = new TimeSpan(24, 0, 0);
            CreateAlarm(alarmCallback, alarmTime, dailyTimeSpan, false);
        }

        public static void RunOnDelay(AlarmCallback alarmCallback, int runInMilliseconds)
        {
            DateTime alarmTime = DateTime.Now.AddMilliseconds(runInMilliseconds);
            CreateAlarm(alarmCallback, alarmTime, TimeSpan.Zero, true);
        }

        public static void RunRepetitively(AlarmCallback alarmCallback, int repeatMilliseconds)
        {
            DateTime alarmTime = DateTime.Now.AddMilliseconds(repeatMilliseconds);
            TimeSpan repeatTimeSpan = new TimeSpan(0, 0, 0, 0, repeatMilliseconds);
            CreateAlarm(alarmCallback, alarmTime, repeatTimeSpan, false);
        }
        #endregion

        #region Private Methods
        private static void CreateAlarm(AlarmCallback alarmCallback, DateTime alarmTime, TimeSpan timeSpan, bool removeAfterRun)
        {
            if (_alarmHashtable == null)
                _alarmHashtable = new Hashtable();
            
            _key=_key+1;

            AlarmData alarmData = new AlarmData();
            alarmData.Key = _key;
            alarmData.Callback = alarmCallback;
            alarmData.ExtendedTimer = new ExtendedTimer(OnExecuteAlarm, alarmData, alarmTime, timeSpan);
            alarmData.RemoveAfterRun = removeAfterRun;

            _alarmHashtable.Add(_key, alarmData);
        }

        private static void OnExecuteAlarm(object target)
        {
            AlarmData alarmData = (AlarmData)target;
            
            if (alarmData.RemoveAfterRun)
                _alarmHashtable.Remove(alarmData.Key);

            alarmData.Callback.Invoke();
        }
        #endregion
    }
}

The Main .NET Micro Framework Program

There is an event handler for the Ethernet Communication that runs when a message is received.

EthernetCommunication.EventHandlerMessageReceived += new MessageEventHandler(OnMessageReceived);

The OnMessageReceived method parses the message and calls the methods to execute the commands. The code snippet below is only partial, but the full source is available for download at the top of this article.

        private static void OnMessageReceived(string message)
        {
            string[] parts = message.Split(' ');
            switch(parts[0].ToUpper()) 
            {
                case "M":
                case "MOVE":
                    if (parts.Length != 3)
                    {
                        EthernetCommunication.SendMessage("The move command takes 3 arguments.");
                        break;
                    }
                    int leftRightAngle = int.Parse(parts[1]);
                    int upDownAngle = int.Parse(parts[2]);
                    _squirtGun.MoveToPosition(leftRightAngle, upDownAngle);
                    break;

                case "U":
                case "UP":
                    int upDelta = parts.Length > 1 ? int.Parse(parts[1]) : 1;
                    _squirtGun.UpDownAngle = _squirtGun.UpDownAngle + upDelta;
                    break;

About the Author

Follow Dan on twitter: @LogicalDan

Dan graduated summa cum laude from North Carolina State University with dual degrees in Electrical Engineering and Computer Engineering. Dan attended NC State on full scholarship program with General Motors. After working with GM, Dan served as application development director for the largest Microsoft Business Solutions Partner in the Carolinas. During this time, Dan's team won two Microsoft Pinnacle awards. For the past 10 years, as Co-Founder and Chief Technology Officer of, Logical Advantage (www.logicaladvantage.com), a software consulting business, Dan has successfully architected and delivered web-based and mobile applications for many Fortune 500 companies. Dan focuses his energies on emerging technologies, and ensuring that all projects are architected to meet the client's current and future needs. Dan collaborates with his Chief Solutions Officer and other architects to create technical standards, including coding standards, tools, and platforms. He holds a leadership role in the local Microsoft Enterprise Developer's Guild and has been on the steering committee for over a dozen years.

Download the Source Code

Click this to download the source code for the netduino .net micro framework projects.

Using jQuery Mobile with MVC and Netduino for Home Automation

Click this link to read part 2 of my home automation projects: Using jQuery Mobile with MVC and Netduino for Home Automation

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Dan Thyer
Chief Technology Officer Logical Advantage
United States United States
Member
Dan graduated summa cum laude from North Carolina State University with dual degrees in Electrical Engineering and Computer Engineering. Dan attended NC State on full scholarship program with General Motors. After working with GM, Dan served as application development director for the largest Microsoft Business Solutions Partner in the Carolinas. During this time, Dan's team won two Microsoft Pinnacle awards. For the past 10 years, as Co-Founder and Chief Technology Officer of, Logical Advantage (www.logicaladvantage.com), a software consulting business, Dan has successfully architected and delivered web-based and mobile applications for many Fortune 500 companies. Dan focuses his energies on emerging technologies, and ensuring that all projects are architected to meet the client's current and future needs. Dan collaborates with his Chief Solutions Officer and other architects to create technical standards, including coding standards, tools, and platforms. He holds a leadership role in the local Microsoft Enterprise Developer's Guild and has been on the steering committee for over a dozen years.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5groupnayeemsazzad13 Jan '13 - 11:10 
Excellent !!
GeneralRe: My vote of 5memberDan Thyer14 Jan '13 - 1:59 
Awesome! Thank you
GeneralMy vote of 5memberWESTSEYI21 Nov '12 - 15:13 
Excellent
GeneralRe: My vote of 5memberDan Thyer26 Nov '12 - 10:47 
Thanks!!
GeneralMy vote of 5memberManar Ezzadeen17 Nov '12 - 9:03 
nice article
GeneralRe: My vote of 5memberDan Thyer18 Nov '12 - 10:05 
Thanks!!
GeneralMy vote of 5memberdevvvy1 Nov '12 - 20:08 
love automation!
GeneralRe: My vote of 5memberDan Thyer2 Nov '12 - 2:13 
Thanks!!
GeneralRe: My vote of 5memberdevvvy2 Nov '12 - 15:42 
Dan, ever notice, Brits and Japs are especially obsessed with mechanical devices? Two fascinating civilization you can actually seen many parallel runs between the two
dev

QuestionSource CodememberDarkMoonDervish17 Aug '12 - 1:38 
Would it be possible to share the source code? I've double checked it on the top of the page, but found nothing. Thank You in advance.
AnswerRe: Source CodememberDan Thyer20 Aug '12 - 6:05 
There is a link at the bottom of the article with the source code for the netduino projects. Are you looking for the source with the Kinect SDK? I'm happy to give out that code too, but I did not spend any time on that code to make it presentable and I built wrote that code with the beta version of the SDK.
GeneralRe: Source CodememberDarkMoonDervish2 Oct '12 - 21:50 
Sorry, I must have missed the link, it's all there - thank You. I've got however another question (and kind request indeed). Because the fact I'm starting up my netduino adventure - I'd appreciate it very much to have a look at Your project schematics (parts connection schemas) - if possible of course. By glancing at the netduino image on site I've seen some custom equipment attached to it - is it a prefabricated shield for ardruino/netduino? I've seen few of them (motor shield, sensor shield) - Your version seems to be different (or customized). Thank You in advance and also for any tip concerning the project Smile | :)
GeneralRe: Source CodememberMember 43757034 Jan '13 - 8:50 
I would be very interested in the Kinect-NetDuino code. I am going to make a home automation device to control lights, fans & time on either the Xbox &/or computer for the boys.
 
This is going to be tied to my phone so I can see if they are still on & kill the devices remotely & allow the boys to turn fan/lights on & off with their boy or voice.
GeneralMy vote of 5memberranger1119 Jul '12 - 21:33 
excellent
GeneralRe: My vote of 5memberDan Thyer20 Aug '12 - 5:55 
Thanks!!
QuestionNice efforts..memberneriacompany27 May '12 - 22:40 
Nice efforts..
NERIA COMPANY
info@neriacompany.com
Thank you!
ipad games | kiralık tekneler | rc helicopter

QuestionSomething I don't see everyday - My vote is 5memberMpho aka Zazo12 Apr '12 - 22:26 
Thumbs Up | :thumbsup:
Awosome work
 
How to contact u ?
AnswerRe: Something I don't see everyday - My vote is 5memberDan Thyer15 Apr '12 - 5:20 
Thanks! I sent you an email with my email address in it. Let me know if you do not get it.
GeneralRe: Something I don't see everyday - My vote is 5memberMpho aka Zazo15 Apr '12 - 20:26 
Hi Dan
 
I didn't get it ,can you resend it again ....
GeneralRe: Something I don't see everyday - My vote is 5memberDan Thyer16 Apr '12 - 3:24 
How about now?
GeneralRe: Something I don't see everyday - My vote is 5memberMpho aka Zazo16 Apr '12 - 20:33 
Hi Dan
 
Still nothing .
But what I wanted to know id the following :
 
- The mobile applications are running locally on the devices ? If so how did you manage to have them installed on the devices.I though jqmobile is an mobile web app which hosted on web server.
 
- How do u manage to linked up an code behind(MVC 3) with mobile app(since it's using html5 and jQmobile).
 
- Just an explanation especially on how technical settup and which emulators/browser used for testing .
 
my email address - mphowalter@ananzi.co.za
QuestionGood workmemberMember 456543330 Mar '12 - 10:35 
Best article I've seen on this web site for ages
 
5++ from me
AnswerRe: Good workmemberDan Thyer30 Mar '12 - 10:43 
Wow - thank you! I really appreciate your compliment!
QuestionVote of 5 indeedmemberMartin Jimenez13 Mar '12 - 8:50 
Dan can you please give us a list of the hardware used? water valves, motors, etc
 
Thanks for a great article.
AnswerRe: Vote of 5 indeedmemberDan Thyer30 Mar '12 - 10:48 
Most of the stuff that I used was all standard stuff that came from the hardware store or Radio Shack. I got the netduino plus from the www.makershed.com. I'll see if I can get you a more complete list and post on the article.
QuestionI want to thank you, indeed. [modified]memberkartalyildirim3 Mar '12 - 6:36 
I want to thank you, indeed.


modified 23 Mar '12 - 6:57.

AnswerRe: I want to thank you, indeed.memberDan Thyer3 Mar '12 - 6:40 
Awesome! Thank you
GeneralMy vote of 5memberRC_Sebastien_C19 Feb '12 - 4:57 
Excellent. Thanks!
GeneralRe: My vote of 5memberDan Thyer20 Feb '12 - 4:36 
Thank you!
GeneralMy vote of 5memberDavid Catherman17 Feb '12 - 2:37 
good implementation
GeneralRe: My vote of 5memberDan Thyer17 Feb '12 - 9:27 
Thanks David!
QuestionGreat article!memberMember 865313216 Feb '12 - 12:06 
I'm impressed with how you're extending the functionality.
AnswerRe: Great article!memberDan Thyer16 Feb '12 - 12:50 
Thanks you!!
GeneralMy vote of 5memberkurtlog16 Feb '12 - 11:05 
Dan is the man. Of Course!
GeneralRe: My vote of 5memberDan Thyer16 Feb '12 - 12:49 
Thanks man!!
Questionsome doubtsmemberkamaloo9 Feb '12 - 6:35 
yes i have been having this kinda doubt , i like and im used to microsoft technologies .. i wanted to make home,office, car automation ..using my windows phone 7 as a remote control ...how well did it go for u ? winphone7 can control netduino? or u did something else ?
AnswerRe: some doubtsmemberDan Thyer9 Feb '12 - 7:26 
My first project was controlling the servos for the pool with wp7. The silverlight environment on wp7 was shockingly easy to learn and very easy to use to call a web service. I also wrote a simple Android app for the garage door. Wp7 was easier for me to learn than Android, but my background is largely Microsoft. The Android environment was not too bad and I was able to get the app completed in a day. I'm now writing a HTML5 version using jQuery mobile so that it will work across all my devices. I'll post an article soon about the project. I recommend for you to build your project with HTML5 and jQuery mobile so that you can use it on all your devices and not just your wp7.
GeneralMy vote of 5memberMihai MOGA8 Feb '12 - 6:35 
Great article. Please keep it up!
GeneralRe: My vote of 5memberDan Thyer9 Feb '12 - 7:02 
Thanks!!!
GeneralMy vote of 5mentorMd. Marufuzzaman7 Feb '12 - 19:41 
Very nice Smile | :)
GeneralRe: My vote of 5memberDan Thyer9 Feb '12 - 7:02 
Thank you!
GeneralMy vote of 5memberJαved6 Feb '12 - 23:27 
Awesome.
GeneralRe: My vote of 5memberDan Thyer7 Feb '12 - 7:43 
Thanks!!
Generallike !!!!!memberraananv27 Jan '12 - 12:27 
Smile | :) Smile | :) Smile | :) Smile | :) Smile | :) )Smile | :) Smile | :) Smile | :) Smile | :)
GeneralRe: like !!!!!memberDan Thyer28 Jan '12 - 4:45 
Awesome - Thank you!!
GeneralRe: like !!!!!memberDan Thyer29 Jan '12 - 13:04 
Thank you!!
GeneralMy vote of 5memberAbinash Bishoyi27 Jan '12 - 8:23 
Great !!!
GeneralRe: My vote of 5memberDan Thyer28 Jan '12 - 4:45 
Thank you!!
GeneralMy vote of 5memberCollin Jasnoch26 Jan '12 - 5:22 
Very kewl indeed!
 
I have been wanting to do similar things, but my current lifestyle does not provide much time. This has been bookmarked for when I do. Thank you!
GeneralRe: My vote of 5memberDan Thyer26 Jan '12 - 10:36 
Awesome! I would love to hear about what you build.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 12 Mar 2012
Article Copyright 2012 by Dan Thyer
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid