Netduino home hardware projects downloads community

Jump to content


Photo

Web Based IR Remote


  • Please log in to reply
25 replies to this topic

#1 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 04 July 2012 - 06:25 PM

EDIT: For the completed code, please check out this post.

 

Hello,

So I've been playing around with the Netduino Plus and the Netduino Mini for a little while now (when I have the time) and I'm about to embark on my first major project. I was hoping to post the idea here and get some feedback on it, along with a little help getting started.

This idea was mostly inspired by the heatwave over here on the East Coast. The overall concept is that I'd like to be able to control my AC unit (which has an IR remote) with my Netduino Plus, and then eventually hook it up to the internet so that I can control it from pretty much anywhere.

I realize that's pretty ambitious, so I've broken it down into steps I can take to make it more manageable:

1) First I need to figure out how to generate the IR signal from my Netduino. I've done a little research and I came across this post:

http://highfieldtale...r-for-netduino/

It looks pretty promising, but I'm having trouble finding the schematics in the .NET Micro Framework Toolbox, it's possible I'm missing something though. I'm wondering if this might be a bit more complicated than I need. I also found this post, which uses an Arduino, that might be a simpler way to create a remote:

http://www.zovirl.co...ith-an-arduino/

Any thoughts on which might be best, or any other alternatives, would be great.


2) Second, I need to capture the IR signal from my remote so that I can reproduce it on the Netduino. This is the step that I probably need to most help with. I don't have an oscilloscope, and I'm really trying to do this project on a shoestring budget (hopefully no more than $20 or so, since I already have the Netduino). Thus, I'm wondering if I can use my Netduino, along with this IR receiver diode, to decode my remote. Ideally, I could even use this receiver to eventually make my remote programmable from any standard remote (TV, AC, ceiling fan, etc...).

If the IR receiver won't work, I also stumbled across this alternative to an oscilloscope using a solar cell:

http://www.instructa...sy-Light-Probe/

Though I'm worried the IR signal from the stock remote won't be able to stimulate a current on the solar cell because the work function might require higher energy photons. I don't know what the maximum wavelength is that can still create a current in most solar cells.


3) Penultimately, I'll use the excellent web server code I found on this forum to make the remote network controllable.


In the future I also hope to integrate a temperature sensor that will upload temperature data of my apartment to an SQL database, and maybe some other sensors depending on how things go.

So that's my project idea in a nutshell, I just need to be pointed in the right direction so that I can get started. Any thoughts or suggestions would be greatly appreciated. I'm sure it'll take a while before I make any real progress, but I'll be certain to keep a record of how things go, and post code and schematics if I manage to have any success.

Thanks in advance for the help!


Edited by ShVerni, 08 July 2013 - 02:27 AM.


#2 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 04 July 2012 - 08:14 PM

Hi ShVerni!

I've also been thinking a lot of making a network attached IR-transmitter using a Netduino. I was thinking of using the mini now that we've got mIP.

IR-signals are actually very simple in their nature
They're normally just a series of ON/OFF-pairs (high and low pulses) modulated on a 38kHz carrier or sometimes some other frequency not far from that. Modulation of symbols are based upon the duration, i.e. for how how many periods the signal is ON (high) and OFF (low) respectively. I guess you can say that IR is a sort of variable frequency PWM.

Virtually all protocols can be broken down into this (I think Bang Olufsen diverges from this but they're pretty much the only ones). The challenge probably lies in using a Netduino as the generator.

First thing is you need to find out what IR-sequences to send in order to make your piece of AV equipment perform a certain task, like changing the channel on your TV or adjusting the volume on your stereo. For this you can find a lot of so called Philips Pronto HEX-codes on the internet.

However, If you have a smartphone (any Android or an iPhone), an iPod or an iPad, a much easier way would be to use the 3-month trial version of iRuleAtHome which is an smartphone app and a web based IR remote design application. That software gives you access to thousands of devices and their IR-sequences formatted as on/off-pairs (like described above) and it looks really good too.

Ok, so iRuleAtHome has all the codes but how do you extract them from there?
Easy, I've worked a lot with a ready made network attached IR-transmitter called the iTach from Global Caché. This little thing has its own tcp/ip based protocol that it uses to receive commands from another device on the network. When running the iRuleAtHome smartphone app on a device, that device becomes the sending device from which iTach can receive commands via its protocol and carry out the orders by sending the corresponding IR sequences from one of its three IR ports. It's actually a very simple protocol.

Anyway, I've developed a software library (.NET assembly) called iTach toolkit which would be of much use to you. You can use the toolkit to create a virtual iTach that receives IR-commands from the iRuleAtHome app over your WLAN or wired network. The app will think that its talking to a real physical iTach on the other end, but in reality its the toolkit running on a PC. When the virtual iTach receives any and all IR-sequences, you simply store them into a file and then send them to /dev/null.

Here's a thread i wrote on the iTach toolkit (also contains a link to open source on CodePlex)
http://forums.netdui...m-a-smartphone/

If you don't have an smartphone or similar device, you can use an Android port for x86 and install on a regular PC to run the app on that. Even though its very convenient to use an Android or iOS device as a remote to send IR commands through your IR-transmitter to be (trust me), they're not really required to achieve you goal and can be used merely as a tool to extract the IR-sequences from iRuleAtHome.

Go for a standard protocol
I own an iTach and have been using the family set of iPods, iPads and iPhones to controll all kinds of equipment for a couple of years. I even built my own radio transmitter extension so that I can control lighting fixtures and wall outlets (I use this every year for the Christmas tree). Still I think it would be cool to build my own version of the iTach, possibly with more features added to it. Now I'm very excited to learn that you might set out to do this.

Even if you decide not to go in the suggested direction, I strongly recommend that you still implement the iTach network protocol onto your transmitting device (Netduino) - this is because virtually all IR sending devices, remote apps, home control systems, etc support the iTach protocol and if you make your device compliant it can work together which any and all of the other systems. The iTach protocol can also used for other stuff like rs232, relay control, reading state of switches, etc.

You can read more of the protocol by reading this PDF, it also explains very well how IR-sequences are constructed, generated and interpreted:
http://www.globalcac...s/API-iTach.pdf

How to generate the IR signals?
When it comes to this, I was thinking of using the PWM of the Netduino. My idea is to start the PWM using a fixed duty cycle around 20 to 50% at 38kHz and then toggle another pin according to the number of ON and OFF periods respectively. I would then perform a logical AND with the output of the latter pin and the PWM output using some 74xx logic and voila - you got an IR signal.

It could well be that the Netduino is too slow to toggle the pin at the correct points in time (with respect to the PWM signal) and then you might be able to use the UART by carefully selecting what data to send and then perform a logical AND of that and your PWM output.

Since you're using PWM (one way or another) you can feed the IR LED more power than its specifications say (maybe several times as much) as long as you keep below 50% duty cycle. This will increase the distance range of your transmitter without blowing up your IR LED.

Good luck and keep us updated!

#3 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 04 July 2012 - 09:44 PM

Thanks for the very detailed reply! There's a lot of useful information in there, and the iTach protocol looks very useful, and I may be able to implement it. Unfortunately, I don't think the iRule remote will work for me, I checked the device database and there isn't a listing for a Haier air-conditioning unit. I'm afraid I'll need to determine the the sequences of hi and low pulses from my remote manually, hopefully using the IR receiver and the Netduino, if I can figure out how to decode or read the signal. The information you provided on the nature of IR remotes will be very useful I'm sure. Thanks again for your help, I'll need to do some research before I fully understand which direction to take.

#4 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 04 July 2012 - 11:14 PM

Unfortunately, I don't think the iRule remote will work for me, I checked the device database and there isn't a listing for a Haier air-conditioning unit. I'm afraid I'll need to determine the the sequences of hi and low pulses from my remote manually, hopefully using the IR receiver and the Netduino, if I can figure out how to decode or read the signal.

The iTach unit I told you about has a little IR eye and a learning capability so you simply direct your remote towards it and get the HEX codes in clear text on your PC. The unit is available (wired, wifi and with/without PoE) from SmartHome in the USA. Buy one, learn the codes and return itPosted Image I think these are also sold at www.iruleathome.com

When you got the codes, the iRule remote app will work for you but the lifetime license is about 40 USD if I remember correctly.

#5 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 04 July 2012 - 11:24 PM

...and then there's these two posts about reading IR using a Netduino:

http://forums.netdui...col-ir-decoder/
http://forums.netdui...s-from-remotes/

The first one I use myself, it'll give you a number but might be able to rewrite to produce the whole sequence. Though I doubt the Netduino can handle a 38kHz interrupt so I'm not really sure how it works.

Also, you don't need a proper receiver, you can just use a simple 1$ IR photodiode.

#6 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 05 July 2012 - 12:16 AM

Awesome, thanks! I'll look into it those, though I think I'll start by using the photodiode, as that seems the most economical, and also will help me learn the most about IR transmission and reception.

#7 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 05 July 2012 - 07:20 AM

Awesome, thanks! I'll look into it those, though I think I'll start by using the photodiode, as that seems the most economical, and also will help me learn the most about IR transmission and reception.

Sorry, I wrote photodiode last night when actually meant one of these:

http://www.sparkfun.com/products/10266

It's got a built-in pre-amplifier and requires no (or very few) external components compared to the simple photodiode.

EDIT: Also found this article on how to build you own IR capture device:
http://www.instructa...-Visualization/

#8 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 05 July 2012 - 03:13 PM

Perfect, that was the receiver diode I was originally looking at, and that IR Widget looks very useful!

#9 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 14 July 2012 - 03:25 AM

Hey, I just wanted to post an update on my progress, in case anyone was curious.

Mostly I've been researching and practicing my C# while I wait for parts to arrive. I taken the web server code I found here and I've expanded it in several ways (I know i could have used NeonMika's web server, but I'm still very new to C# and that was a little too complicated for me to just dive right in and start customizing):

1) Added some very basic security using cookies (and added cookie support).
2) Added a thread that syncs the time on the device with NIST using NTP every 24 hours.
3) Added caching support to allow browsers to cache data and reduce the load on the server.
4) It starts two listener threads to handle requests a little faster (two at a time).

I realize these are relatively minor achievements, and I've probably been very inefficient, but as my first C# project, I've managed to learn a lot. I'd be happy to pot the code if anyone's interested.

Now, on to the actual IR remote part of this. I did end up using this oscilloscope alternative:

http://www.instructa...sy-Light-Probe/

only I used an IR photodiode instead of a solar cell, and it worked beautifully (image below), it captured the signal from my remote very nicely. Generating the IR signal was a little more difficult. I did end up using the PWM, and since I didn't have an AND gate handy (I'm working on fixing that) I just turned the PWM on to 36 kHz and off again to create the pulse. To create the timing for the pulse I use a method that is admittedly pretty silly, I just run empty for loops for X number of iterations to get the right timing. Here's an example of my code (I truncated the commands array for the post, because it's ridiculously long):

    class IRControl
    {
        static private PWM IR;
        static private int[] command;
        static object monitor = new object();
        //Add your IR commands here.
        static private int[][] commands = {
            new int[]{1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, ...}
        };


        public IRControl(Cpu.Pin pin) 
        {
            //Set the PWM pin.
            IR = new PWM(pin);
        }

        //This reiecives an int, which is the IR command to send.
        public void Send(int sig)
        {
            //Set the command to the requested one.
            command = commands[sig];
            var sendThread = new Thread(pulseLED);
            //Create a high priority thread.
            sendThread.Priority = ThreadPriority.Highest;
            //Start the thread to send the command.
            sendThread.Start();
        }
        
        private static void pulseLED()
        {
            lock (monitor)
            {
                Debug.Print("Sending signal");
                //Make sure the LED is off.
                IR.SetPulse(0, 0);
                for (int i = 0; i < 11; i++) { }
                //Set the period of the signal modulation (28 microseconds is ~36 kHz).
                const uint period = 28;
                //I found setting the duration to half the period yielded the strongest signal. 
                const uint duration = 14;

                //Send the opening part of the command.
                IR.SetPulse(period, duration);
                for (int i = 0; i < 226; i++) { }
                IR.SetPulse(0, 0);
                for (int i = 0; i < 113; i++) { }
                //Process the command.
                foreach (int bit in command)
                {
                    if (bit == 1)
                    {
                        IR.SetPulse(period, duration);
                        for (int i = 0; i < 11; i++) { }
                        IR.SetPulse(0, 0);
                    }
                    else
                    {
                        for (int i = 0; i < 11; i++) { }
                    }
                    for (int j = 0; j < 9; j++) { }
                }
            }

        }
    }

Which seems to work pretty well:

Posted Image

The top is the signal produced by my remote, the bottom by my code. More amazingly, it actually works on my AC unit, but I think for loops are probably not the best way to time it. I start the thread as high priority so that it will have almost exclusive use of the processor, to keep the timing consistent, this essentially uses the clock speed of the Netduino as the timer. I also enclose the actual send command in a lock so that it won't try to send two commands at once.

It would probably be better to use the SPI or something like it for the pulse timing, but I don't really know how to use the SPI port yet. Anyway, that's where I am right now, there's a lot I need to do to clean things up and get thing running more efficiently, and if anyone has suggestions on how to time the pulse widths better, or on anything else, I'd love to hear them!

Thanks in advance.

#10 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1717 posts
  • LocationVenezia, Italia

Posted 14 July 2012 - 07:31 AM

I'd not bet anything on the reliability of a simple for loop, essentially because the unpredictable behavior of the managed framework. However that was a great success anyway. Probably the spi-way is more stable regarding the timing. As soon you'll have more services to manage (e.g. The web server), the GC will work a lot more inserting a lot of delay in the message Damn! Writing this post using a phone while running in the train is much like climbing a mountain!
Biggest fault of Netduino? It runs by electricity.

#11 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 14 July 2012 - 08:47 AM

Really cool ShVerni, so you went for a soundcard oscilloscope then, very nifty and really nice work on the web server too.

Btw, what is the max sampling frequency of your soundcard?

About the timing, an option that I considered was using an interrupt handler on the Netduino. Here's how I imagined doing this:

1. Set pwm to a fixed 36kHz and for example 20% duty cycle
2. Connect the pwm output signal to an interrupt pin
3. Handler does the timing by counting pwm pulses (i.e. no of interrupts)
4. Handler outputs the "ANDed" IR-signal on a separate outputpin according to the pulse series you want to generate.

I'm not sure the Netduini us fast enough but maybe you could try it? Its software "bit-banging" as they call it.

If this does not work, SPI is really simple to use and figuring out what data to send should be quite easy too. The synchronization between starting an SPI write and the PWM pulses might be tricky but could be initiated from an ISR like above. Together with an AND gate, I agree with Mario that this solution would yield the best results and would also require much less processing power from the Netduino.

EDIT: Silly me, it just occurred to me that you might be able to do it all by using the SPI data line alone.

#12 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 14 July 2012 - 01:42 PM

Thanks for the great replies, I completely agree that for loops are not a permanent solution, more just a proof of concept to make sure I was understanding the basics of IR. I definitely think SPI is the way to go, so I'm going to spend a little time learning about that, let me know if you have any suggested reference materials. As for the oscilloscope, the sampling rate of my sound card did, at first, present a problem. On my laptop, which has a max sampling rate of 48 kHz, I could see the signal peaks, but I couldn't resolve the actual modulation frequency of the IR signal. Fortunately, my desktop has a max sample rate of 128 kHz (although Audacity only supports up to 96 kHz), which was fast enough to resolve the modulation frequency. So I would definitely recommend the sound based oscilloscope with the caveat that you need a sound card with a high sampling rate. Thanks again, I'll be sure to let you know how I progress using the SPI solution. Edit: I just wanted to point out that the IR signal I generated was from the web server, i.e. I had all the server processes running, and used my browser to trigger the signal. This doesn't make the for loops a good solution, but it might provide some insight on how the framework operates.

#13 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 14 July 2012 - 03:23 PM

Nice!

Regarding use of SPI classes, you could take a look at the wiki on how to set up SPI transfer. You'd only be doing writes without anyone listening on the other end which will make it simpler.

I was wondering how you managed to measure a 36kHz signal with a 48kHz soundcard because it would be subject of folding effects but the 96kHz card explains it.

The bit-banging method I suggested should be quickly implemented - I would be very interested in knowing if the Netduino can keep up, have you tried it and if not, could you perhaps?

Edit: I just wanted to point out that the IR signal I generated was from the web server, i.e. I had all the server processes running, and used my browser to trigger the signal. This doesn't make the for loops a good solution, but it might provide some insight on how the framework operates.

Nice to know there seem to be some performance head room after all, cool.

Keep up the nice work and be sure to keep us updated!

#14 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 14 July 2012 - 11:32 PM

I'm going to try both methods, the bit-banging method first since it seems simpler to implement. I'll be sure to let you know how it goes.

#15 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 17 July 2012 - 12:18 AM

Gr8, looking forward to hear of your findings!

#16 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 20 July 2012 - 03:24 AM

Hello again,

I have another update on my efforts with this project. I'm pleased to say that using the IR example I found Here I was able to implement a rather primitive form of the SPI transmitter, which worked very nicely. I haven't implemented the swanky ushort codec, but it looks like a great idea. The image below shows how the SPI method compares to the for loops and the original remote:

Posted Image

The SPI method is on bottom and, as you can see, there are a few artifacts poking up randomly in some of the spaces. I couldn't figure out how to get rid of those, but since they don't seem to cause a problem, I just ignore them.

I actually had a lot more difficulty with the bit-banger method, and eventually gave up on it, for now. What I tried to do was start another PWM at 40 microseconds (the fastest PWM setting the wouldn't cause a crash) and use that as a timer by counting interrupts. However, for whatever reason, when trying to count the interrupts the counter would increment, but the Netduino would lock-up after just one counting. That is to say, it would turn on the diode for one pulse, then lock up. I'm not really confident in this method anyway, because I'm afraid it would miscount, especially if other threads are running. I've attached the unfinished code I was using to test that if you're curious. I've also attached to code for the generalized form of the entire server, it could probably do with a bit of cleaning up as well, but maybe others who want a web controllable IR remote will find it useful.

I appreciate all the help, I think the SPI method is probably the most reliable so I will stick with that solution. Eventually I want to be able to record IR commands, like a programmable remote, but that's going to be a while in the making.

 

EDIT: I've posted the completed and updated code to this post.

Attached Files


Edited by ShVerni, 08 July 2013 - 02:27 AM.


#17 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 21 July 2012 - 07:26 AM

Great findings, sorry for leading you astray with the bit bang thing, I doubted that the Netduino would cope but I didn't expect it to lock up. I think you can ignore the SPI artifacts since the receiver wont notice them. What SPI clock speed did you use?

#18 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 22 July 2012 - 05:31 PM

I think I'm probably just demanding too much from the PWM, the whole device doesn't lock up, just the tread, but anyway, it was good to learn the limitations of the hardware.

As for the SPI, I used Mario Vernari's method and calculated the SPI clock as follows:

//Calculates the actual period for pushing out one
//ushort value, interleave including.
float carrier = 1 / frequency;
this.bitTime = carrier - 2e-3f;

//calculates the equivalent SPI frequency,
//note that an "unshort" is 16 bits.
uint spi_freq = (uint)(16.0f / bitTime);

Where I passed a frequency of 36.0f for 36 kHz.

An interesting aside: I upgraded the firmware to 4.2RC5 for the extra RAM, and also so I could use Regex, and my deployment jumped from ~15KB to ~35KB, which seems like rather a lot. I was just curious if this was to be expected when using the additional Regex references, and the 4.2 framework in general.

#19 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 22 July 2012 - 07:55 PM

20k sounds like a lot but then again, regexp is more complex than meets the eye...

#20 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 125 posts
  • LocationNew York, New York

Posted 23 July 2012 - 12:33 PM

All too true, we may never fully understand its mysteries...




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2010-2014 Secret Labs LLC  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.