Laurent Ellerbach

Ce blog est principalement destiné à publier des informations relatives à Microsoft, à ses technologies, aux outils Visual Studio et à ses versions Express notamment Visual Basic

  • Laurent Ellerbach

    .NET Microframework on RaspberryPi (Part 1)

    • 3 Comments

    I’m a bit fan of .NET Microframework (NETMF). NETMF is an open source technology originally developed by Microsoft based on .NET. It directly run on metal, without any OS. All sources and portability kit are freely available On Codeplex: http://netmf.codeplex.com/.

    And as a fan of Embedded devices I had to buy this inexpensive RaspberryPi http://www.raspberrypi.org/. I bought the version second revision with the network adaptor. Advantage is clearly the price and having access to couple of GPIO like SPI,k i2c, PWM, serial and couple of other digital IO. Now it’s a slow device when using the user interface, there is no analog input or output, PWM is limited to only 1 hardware PWM and not really flexible for setting the frequencies. But overall, for the price, it’s Worth playing a bit with it.

    In term of environment, it runs under Linux, it was a very long time I did not had to setup and make a Linux working. I was just reminding couple of commands. And I’m far to be a Linux developer… so I’ve started to look at what to put that looks like C# or .NET on this board and more specifically .NET Microframework.

    I was disappointed to see that NETMF is not on the platform. But happy to see a good implementation of Mono http://www.mono-project.com/Main_Page. So at least I was able to run some .NET code on the Raspberry and take the advantage of the display if needed with Windows forms.

    So what for access like we do in NETMF to the GPIO? I started to search on the web for what is possible to do. And I found a first project RaspberryPi.Net: https://github.com/cypherkey/RaspberryPi.Net/. This project is using one library to access the BCM2835 chipset where the GPIO are managed. I found the last version of the library here: http://www.airspayce.com/mikem/bcm2835/

    And I just followed the steps explained on the RaspberryPi.Net project page. Here are the steps. Open an LXTerminal and type:

    sudo apt-get update

    sudo apt-get install xrdp

    this second one will allow you to access your Raspberry thru RDP Sourire So you can do remote desktop on your Raspberry as you do with any other Windows machine.

    sudo apt-get install mono-runtime

    this will install Mono and all what is needed to run a .NET program.

    sudo apt-get install git

    Very useful if you need to download Git projects. I’ll explain how to use it in the next part of this article as I’ve used it.

    Now we go thru the download of the BCM2835 library, the compilation, the installation:

    wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.25.tar.gz

    tar -zxvf bcm2835-1.25.tar.gz

    cd bcm2835-1.25

    ./configure

    make

    sudo make install

    cd src

    cc -shared bcm2835.o -o libbcm2835.so

    cd

    rm bcm2835-1.25.tar.gz

    Now, you have to copy the libbcm2835.so library with the executable you’ll produce at the end. And for the moment you’re done with the RaspberryPi.

    Go on Windows, download the code from https://github.com/cypherkey/RaspberryPi.Net/, open the project in Visual Studio, if like me you’re using the 2012 version, you may have to change the target to .Net Framework 4.0, change the pin you want to use to put a led, compile the project, put the exe and the so on a USB stick for example, or use any other way to copy it on your Rapsberry.

    image

    I’ve used GPIO 7 (pin 11 on the board), ground on pin 9, I put a Led and a 60 ohms resistor.

    Use this site as a reference to know which pin does what: http://elinux.org/Rpi_Low-level_peripherals. Very well done, with all the details.

    image

    On the Raspberry, run the following command line from the directory you’ve copied the exe and the so file:

    Sudo mono yourprogramm.exe

    of course, yourprogramm here represent the name of the program you’ve done. And in my case I made the link blinking.

    The way it’s working is quite simple. Like in a normal .Net program, you can import external DLL like the system ones. Here, you import the same way but of course not DLL but object. See the following example:

     

    [DllImport("libbcm2835.so", EntryPoint = "bcm2835_spi_transfernb")]
    static extern void bcm2835_spi_transfernb(
    [MarshalAs(UnmanagedType.LPArray)]byte[] tbuf, 
    [MarshalAs(UnmanagedType.LPArray)]byte[] rbuf, UInt32 len);
    

    In this case, it’s interesting as you’ll have to use the Marshaling. And you’ll have to do in a similar way for all the array, strings, pointers and anything what is not a very simple as byte, uint or other. Be also very careful on the length of the parameters, make sure you match them correctly.

    And I’ve quickly implemented a compatible class for Cpu.Pin, SPI, OutputPort and PWM by importing the various functions from the BCM2835 library.

    My main goal was to reuse the maximum of code from an SPI example piloting a 3.5$ Nokia 5110 LCD screen. I reused the code found on the Netduino wiki page: http://wiki.netduino.com/Nokia-5110-LCD.ashx?HL=nokia.

    I did it in couple of hours, exporting the definition from the NETMF code to a new project. As a result, I manage to make it work perfectly on my RaspberryPi!! Cool Sourire 

    image

    Now, I quickly found lots of limitation in the BCM2835 library I’ve used. PWM was not implemented, I found bugs in the SPI part, no support of interruptions, and others.

    So I’ve looked at another library and I found the WiringPi http://wiringpi.com/. This library was a bit more complete. Still not the perfect one but more complete. It does implement SPI, i2c, soft and hard PWM and interruption support for the digital IO. It does support also advanced implementations like the helpers we can find in NETMF.

    And from this points, I’ve used the NETMF portability kit with all the definitions, all the sources to make it as much compatible as possible with NETMF. See my next posts to find more about it and find the Codeplex project associated.

    Ultimately, I’d love to port the full NETMF on RaspberryPi but for this, I’ll need much more time than I have or other very motivated persons.

  • Laurent Ellerbach

    Ultrasound sensor and .NET Microframework (NETMF)

    • 0 Comments

    I recently bought a cheap ultrasound sensor because I want to build a robot. Yes, after the sprinkler management system and the automation of my Lego city, it’s time to play with a robot Sourire. This sensor can measure the distance from 2 cm to approximately 50 cm. Cost is about 5$.

    There are 4 pins:

    • VCC = 5V
    • Trig = send an impulsion and you’ll get a signal back in the Echo pin
    • Echo = the signal back from the impulsion
    • Gnd = ground

    So the usage is very simple, just use 2 pins in the Netduino board, 1 for Trig and 1 for Echo. In terms of code, it will be simple: output the value 1 (high) on the trig pin, then put it back to 0 (low), wait for an answer on Echo pin. Then you measure the time between the value sent and the way back. It will give you the distance. Best is to use the Ticks generated by DateTime. The difference will give 2 times the distance which you’ll have to divide by the celerity of the air (so approx 340 m per second). And that’s for the theory Sourire

    When you look at the reality, it’s always very different Rire. I’ve done measurement and he is the graph with points and ticks every centimeter:

    image

    What we can clearly see is a distortion when the object is close, the distance is not very well evaluated and it’s a pretty much linear curve for the rest. I’ve removed the 1cm point and made a linear regression. The initial point is at 4000 ticks.

    Then the step is about 636 per centimeter. And with those 2 values I can now easily calculate a distance.

    I’ve look at the web to search some existing code and there are existing classes. I pick one which was well written by John E. Wilson and posted in the Netduino forum. I’ve simplified a bit the code and change values for calibration. The simplify code looks like:

        public class HC_SR04
        {
            private OutputPort portOut;
            private InterruptPort interIn;
            private long beginTick;
            private long endTick;
            private long minTicks = 0;  // System latency, 
    subtracted off ticks to find actual sound travel time
    
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="pinTrig">Netduino pin connected to the HC-SR04 Trig pin</param>
            /// <param name="pinEcho">Netduino pin connected to the HC-SR04 Echo pin</param>
            public HC_SR04(Cpu.Pin pinTrig, Cpu.Pin pinEcho)
            {
                portOut = new OutputPort(pinTrig, false);
                interIn = new InterruptPort(pinEcho, false, 
    Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow);
                interIn.OnInterrupt += new NativeEventHandler(interIn_OnInterrupt);
                minTicks = 4000L;
    
            }
    
            /// <summary>
            /// Trigger a sensor reading
            /// 
            /// </summary>
            /// <returns>Number of mm to the object</returns>
            public long Ping()
            {
                // Reset Sensor
                portOut.Write(true);
                Thread.Sleep(1);
    
                // Start Clock
                endTick = 0L;
                beginTick = System.DateTime.Now.Ticks;
                // Trigger Sonic Pulse
                portOut.Write(false);
    
                // Wait 1/20 second (this could be set as a variable instead of constant)
                Thread.Sleep(50);
    
                if (endTick > 0L)
                {
                    // Calculate Difference
                    long elapsed = endTick - beginTick;
    
                    // Subtract out fixed overhead (interrupt lag, etc.)
                    elapsed -= minTicks;
                    if (elapsed < 0L)
                    {
                        elapsed = 0L;
                    }
    
                    // Return elapsed ticks
                    return elapsed * 10 / 636;
                    ;
                }
    
                // Sonic pulse wasn't detected within 1/20 second
                return -1L;
            }
    
            /// <summary>
            /// This interrupt will trigger when detector receives back reflected sonic pulse       
            /// </summary>
            /// <param name="data1">Not used</param>
            /// <param name="data2">Not used</param>
            /// <param name="time">Transfer to endTick to calculated sound pulse travel time</param>
            void interIn_OnInterrupt(uint data1, uint data2, DateTime time)
            {
                // Save the ticks when pulse was received back
                endTick = time.Ticks;
            }
        }

    The value returned is in milimeter. Usage of the class is extremely simple:

            public static void Main()
            {
                HC_SR04.HC_SR04 mUS = new HC_SR04.HC_SR04(Pins.GPIO_PIN_D4, Pins.GPIO_PIN_D5);
                while (true)
                {
                    Debug.Print(mUS.Ping().ToString());
                    Thread.Sleep(500);
                }
    
            }

    That’s it for the Ultra Sound sensor. Next sensor will probably be a presence sensor.

    Enjoy!

  • Laurent Ellerbach

    Adding Bluetooth support to a NETMF board (.NET Microframework)

    • 2 Comments

    I recently bought a very cheap Bluetooth adaptor for my Netduino. I wanted to test how easy/hard it is to support Bluetooth. I see lots of advantages with Bluetooth for a near field communication like piloting easily a robot with a Phone without the need of other network or Infrared. Also Bluetooth is a secured communication with a peering.

    So I bought this cheap Bluetooth adaptor for $8.20. It does expose itself to the world with a serial port on one side and as a normal Bluetooth device on the other side. Communication is supported with a serial port from one side to the other. On a PC, Phone or whatever device, it creates a serial port. So communication is basically very transparent and assimilated to a serial port from end to end.

    JY-MCU Arduino Bluetooth Wireless Serial Port ModuleJY-MCU Arduino Bluetooth Wireless Serial Port Module

    When I received it, I was impatient to test it. First step was to peer it with a PC. I looked at the documentation and found the default name for this device was “linvor” and found out the passkey was 1234. After cabling it with 3.3V (my board support 3.3V to 12V alimentation) and the ground, and approximately 1 minutes, I peered it!

    New step was to write a bit of code to test all this. I decided to do a very basic echo program. So whatever it will receive, it will send it back to the calling program. On the netduino board, I’ll use the COM1 (pins D0 and D1). I found also in less than 1 minute that the default configuration was 9600 bauds, 8 bits, no parity and 1 bit stop. So I wrote this very simple code for the test, very hard to do more basic than that:

    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;
    using System.Text; 
    using System.IO.Ports;   
    
    namespace Bluetooth
    {
        public class Program
        {
            static SerialPort serial;
            public static void Main()
            {
                // initialize the serial port for COM1 (pins D0 and D1)             
                serial = new SerialPort(SerialPorts.COM1, 9600, Parity.None, 8, StopBits.One);             
                // open the serial-port, so we can send and receive data             
                serial.Open();             
                // add an event-handler for handling incoming data             
                serial.DataReceived += new SerialDataReceivedEventHandler(serial_DataReceived);       
                //wait until the end of the Universe :-)
                
                Thread.Sleep(Timeout.Infinite);         
            }            
            static void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)         
            {             
                // create a single byte array             
                byte[] bytes = new byte[1];                
                // as long as there is data waiting to be read             
                while (serial.BytesToRead > 0)             
                {                 
                    // read a single byte                 
                    serial.Read(bytes, 0, bytes.Length);                 
                    // send the same byte back                 
                    serial.Write(bytes, 0, bytes.Length);             
                }         
            }       
            
        }
    }
    

    I launch a simple serial port program like the old Hyper terminal on the PC where I peered the Bluetooth device and ran the test. Good surprise, I selected the port created on my PC (was port 6), open the port. The Bluetooth device went from a red blinking led to a always on led showing the device was correctly peered. Sounds good so far! So I typed “bonjour” and send it. instantly I get the “bonjour” back.

    So cool it’s working! I wanted to know more about the cheap and what can be setup, changes like the name of the device, the pin, the baud rate, etc. I used my preferred search engine Bing and quickly found out that it’s possible to change lots of things by sending couple of AT command. Those commands were used at the old age of modems Sourire It just remembered me that!

    Even if there are lots of cheap existing like the one I bought, most support exactly the same commands. I found a good documentation there. It’s not the same cheap and the AT commands are a bit different but I quickly found out that most were working. So I’ve decided to test if it was working. All what you have to do is send the commands when the device is not peered. You can do it either with a USB to serial FTDI cheap or directly from the board. I did it directly from the Netduino by modifying  a bit the code to send the commands. I found the most interesting commands were the following:

    • AT+NAMEnewname\r\n to change the device name, you get an answer
    • AT+PINxxxx\r\n to change the pin code, default is 1234
    • AT+BAUDx\r\n where X goes from 1 to 8 (1 = 1200 to 8 = 115200) to change the baud rate

     

    I send couple of commands to test and it worked just perfectly Sourire So I renamed the device to LaurelleBT instead of linvor. As the device was already peered, Windows did not had to reinstall drivers or cut the communication, it was just about changing the displayed name:

    image 

    So that’s it! In 5 minutes I had a working Bluetooth module on my board. I was positively surprised and I’ll buy more for sure! Next step it to mount it on a robot and pilot it from a Windows Phone or Windows 8 device.

  • Laurent Ellerbach

    .NET Microframework (NETMF) Web Server source code available

    • 3 Comments

    So as I got lots of asks to get the code of my Web Server, I’ve decided to create a Codeplex project. You’ll find the source here: https://netmfwebserver.codeplex.com/

    It does include the following features:

    • Start, stop, Pause the Web Server
    • Creation of a Web Server on any port
    • Fully functional multithread Web Server supporting GET only
    • Downloading any file present on a SD (or any other physical storage)
    • A full function to get all the parameters of a URL

    Examples of usage can be found on this blog. Working to publish a fully functional example.

    Feedback welcome!

  • Laurent Ellerbach

    Web Server and CSS files in NETMF (.NET Microframework)

    • 2 Comments

    It’s been a long time I did not write anything on my blog. Not that I haven’t developed anything but just because I did not take the time to write proper articles. I’ve continue to add features to my Lego city by piloting the trains but also the switches. And I’ll try to write articles to explain how to do that for all the features.

    But I will start with the modification of my Web Server to support CSS file. I did couple of demonstration of my development and each time I show the interface people were telling to me I need to work with a designer. And that’s what I finally did Sourire I worked with Michel Rousseau who is designer at Microsoft in the French team. And I gave him a challenge: “Design this simple web page without changing the code too much and keep it less than couple of K without any image”. Michel is used to design Windows 8 and Windows Phone apps but not very very simple page like the one I had.

    And he has done an excellent job! Here is the view before and after:

    imageimage

    Now I had to implement this in my code. As the brief was to have minimal effect on the code, I was expecting to implement this quickly. Reality was a bit different. It took me a bit more time than expected for the following reasons:

    • I had to implement in my basic web server a function to be able to download a file (the CSS one)
    • To read and download a file from an SD, you have to do it by chunk as the buffer size is limited (in the case of my Netduino 1024 bit)
    • Modify the main code to care about downloaded file and also add the lines of code to support CSS
    • But the main issue was that I’ve discovered that to be able to have a CSS file, you need to have the specific type “text/css”. This is to avoid cross domain fishing and other hacking

    So let see how to implement this step by step. So let start with the reading part of the file and how to send it. As explained in the last point, a CSS file has to have the correct mime type in the header. In fact, Internet Explorer and most of the other browsers such as Chrome and Firefox does not need the mime type to determine what kind of fire you are downloading. They do it with the mime type and/or with the extension. Most of the time, it’s just with the extension and reading the header of the file. But for security reason, it’s better if you have to determine correctly the type matching with the extension and the header of the file. And for CSS, it is forced like this to reinforce the security in Internet Explorer 8, 9 and 10.

    So as I had to implement this feature for CSS, I made a simple function to support some types I’ll use in other creation:

            public static void SendFileOverHTTP(Socket response, string strFilePath)
            {
                string ContentType = "text/html";
                //determine the type of file for the http header
                if (strFilePath.IndexOf(".cs") != -1 ||
                    strFilePath.IndexOf(".txt") != -1 ||
                    strFilePath.IndexOf(".csproj") != -1
                )
                {
                    ContentType = "text/plain";
                }
    
                if (strFilePath.IndexOf(".jpg") != -1 ||
                    strFilePath.IndexOf(".bmp") != -1 ||
                    strFilePath.IndexOf(".jpeg") != -1
                  )
                {
                    ContentType = "image";
                }
    
                if (strFilePath.IndexOf(".htm") != -1 ||
                    strFilePath.IndexOf(".html") != -1
                  )
                {
                    ContentType = "text/html";
                }
    
                if (strFilePath.IndexOf(".mp3") != -1)
                {
                    ContentType = "audio/mpeg";
                }
                if (strFilePath.IndexOf(".css") != -1)
                {
                    ContentType = "text/css";
                }
    
                string strResp = "HTTP/1.1 200 OK\r\nContent-Type: "
     + ContentType + "; charset=UTF-8\r\nCache-Control: 
    no-cache\r\nConnection: close\r\n\r\n";
                OutPutStream(response, strResp);

     

    So very simple and straight forward code. I do determine the extension of the file I want to read and create a ContentType variable with the right format. Then I build the HTTP header and send the header. Very simple, efficient and straight forward code. We are doing Embedded code, it’s not the code I would do in a normal development of a real web server. But it does the job there!

    Next step is reading the file and outputting it to the Socket. And I do this in the same function, right after this first part:

                FileStream fileToServe = null;
                try
                {
                    fileToServe = new FileStream(strFilePath, 
    FileMode.Open, FileAccess.Read);
                    long fileLength = fileToServe.Length;
                    // Now loops sending all the data.
    
                    byte[] buf = new byte[MAX_BUFF];
                    for (long bytesSent = 0; bytesSent < fileLength; )
                    {
                        // Determines amount of data left.
                        long bytesToRead = fileLength - bytesSent;
                        bytesToRead = bytesToRead < MAX_BUFF ? bytesToRead : MAX_BUFF;
                        // Reads the data.
                        fileToServe.Read(buf, 0, (int)bytesToRead);
                        // Writes data to browser
                        response.Send(buf, 0, (int)bytesToRead, SocketFlags.None);
    
                        System.Threading.Thread.Sleep(100);
                        // Updates bytes read.
                        bytesSent += bytesToRead;
                    }
                    fileToServe.Close();
                }
                catch (Exception e)
                {
                    if (fileToServe != null)
                    {
                        fileToServe.Close();
                    }
                    throw e;
                }
    
            }

    First step is to create a FileStream and create the Stream with the path of the file and read the length of the file. MAX_BUFF = 1024 and is the maximum size of a buffer. It depends on the .NET Microframework Platform. And we will start a loop to read part of the file and send it.

    The System.Threading.Thread.Sleep(100) is necessary to allow some time for the system and other tasks. If you don’t put it and have other tasks, the risk is that the memory will get full very quickly and you’ll block all the code.

    In my Web Server I have an event raised when an HTTP request is done. Here is an example of code you can place in your handling function to manage on one side the files to be downloaded from the SD and on the other side a page you’ll generate dynamically like in ASP, ASP.NET, PHP or any other dynamic language:

                //PageCSS
                if (strFilePath.Length >= pageCSS.Length)
                {
                    if (strFilePath.Substring(0, pageCSS.Length).ToLower() == pageCSS)
                    {
                        string strDefaultDir = "";
                        if (Microsoft.SPOT.Hardware.SystemInfo.IsEmulator)
                            strDefaultDir = "WINFS";
                        else
                            strDefaultDir = "SD";
                        WebServer.SendFileOverHTTP(response, strDefaultDir + "\\" + pageCSS);
                        return;
                    }
                }
                //HTTP header
                strResp = "HTTP/1.1 200 OK\r\nContent-Type: text/html; 
    charset=utf-8\r\nCache-Control: no-cache\r\nConnection: close\r\n\r\n";
                strResp = WebServer.OutPutStream(response, strResp);
    
                // Page util
                if (strFilePath.Length >= pageUtil.Length)
                {
                    if (strFilePath.Substring(0, pageUtil.Length).ToLower() == pageUtil)
                    {
                        ProcessUtil(response, strFilePath);
                        return;
                    }
                }

    Here PageCSS = the file name of the file you are looking for (including the path if in sub directory) so something like “page.css” and pageUtil = name of a page you will generate dynamically (including the path subdirectory) so something like “util.aspx”

    strFilePath = full URL including the parameters so something like “util.apsx?bd=3;tc=4”

    so code looks for the name of the page in the URL and brunch it to a either the SendFileOverHTTP function we’ve just look at or another function in the case of a dynamic page.

    You’ll note also that the is a case in the file part as the default directory is not the same if you are in the emulator or on a real board. The path depend also from the Platform. In the case of my Netduino, it’s CD. For emulator, it’s always WINFS.

    And please do all your file reading brunching before the HTTP header part. As for files, the header is already send out. Which is not the case for the dynamic generated page. As you can send whatever you want including images, text, binary files and you’ll need to set it up correctly.

    Now, lets have a look at the CSS file:

    @charset "utf-8";
    /* CSS Document */
    
    body {
        font-family: "Lucida Console", Monaco, monospace;
        font-size: 16px;
        color: #09C;
        text-align: center;
        margin-left: 0px;
        margin-top: 0px;
        margin-right: 0px;
        margin-bottom: 0px;
    }
    
    a {
        font-family: "Lucida Console", Monaco, monospace;
        font-size: 14px;
        color: #09F;
    }
    td {
        font-family: Arial, Helvetica, sans-serif;
        color: #004262;
        font-size: 14px;
    }
    input {
        font-family: "Lucida Console", Monaco, monospace;
        font-size: 16px;
        color: #09F;
        background-color: #FFF;
        -webkit-transition: all 0s linear 0s;
        -moz-transition: all 0s linear 0s;
        -ms-transition: all 0s linear 0s;
        -o-transition: all 0s linear 0s;
        transition: all 0s linear 0s;
        border: 1px none #FFF;
    }
    
    h1 {
        font-family: Arial, Helvetica, sans-serif;
        color: #FFF;
        background-color: #006699;
        font-size: 24px;
        border: thick solid #006699;
    }
    td {
        font-family: Arial, Helvetica, sans-serif;
        text-align: left;
        font-size: 16px;
    }
    footer {
        color: #09C;
    }
    input:hover {
        background-color: #09F;
        color: #FFF;
    }
    input:active {
        background-color: #003;
    }
    

    As you can see, it is very simple CSS that Michel did. It is just over righting the normal styles with colors and fonts. Nothing really complex but complicated to do something nice in only few lines of code! Well done Michel Sourire

    Now implementation in the rest of the code and all the pages is quite straight forward and simple, here is an example:

    // Start HTML document
    strResp += "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" 
    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
    strResp += "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>Gestion des trains</title>";
    //this is the css to make it nice :-)
    strResp += "<link href=\"" + pageCSS + "?" + securityKey + "\" rel=\"stylesheet\" type=\"text/css\" />";
    strResp += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/></head><body>";
    strResp += "<meta http-equiv=\"Cache-control\" content=\"no-cache\"/>";
    strResp = WebServer.OutPutStream(response, strResp);

    The HTML page is build and the CSS page is added with a parameter (a security key). And this line including the CSS is the only line I have to add to go from the original design to the nice new one!

    So that’s it for this part. I’ll try to find some time to write additional examples.

  • Laurent Ellerbach

    How software can solve hardware problems

    • 1 Comments

    I’ve developed my own sprinkler system and my own humidity sensor. This sensor is extremely simple as you can read in my article. The main problem of this sensor is that the data to be read is an analogic data and the length of the cable is very long. There are lots of problems implied with long cables. You can read an excellent article from Mario Vernari here. In his article, you can clearly see the impact of an alimentation, of other signals into a long distance cable.

    Of course my humidity sensor will follow the same problem. And I’ve logged couple of days of data every minute to have enough data to see how the data looks like.

    image

    As you can visually see the bleu line represents the data and with 19000 data, you can feel like it is very random. In fact those data are not random, they are just noisy. There are couple of solutions to avoid this problem. First solution is of course hardware, changing the hardware to remove a maximum of noise and clear the signal. But I will not do this for my example.

    I will use a pure software solution to remove this noise. As explained in Mario’s blog, most of the noise is kid of high frequency compare to the normal signal. And this apply to any scale. So in my scale, I will also have this issue. What I know is that my signal do not change much. Remember I’m measuring the soil humidity or moisture and this is not changing so quickly. It can change very quickly in less than couple of minutes in case of huge rain.

    So one of the solution is to do a mobile average. By doing this, you can remove the high frequency. The principle is simple, it’s about doing an average of N values that “moves” with the signal. And the effect is to mathematically remove the high frequencies. Let use an example with a period of 15 points. In my graph, that would say an average of a moving quarter. Applied to the previous graph, the black line does represent it:

    image

    and visually, you can see that it does remove lots of the randomness. Of course, if you do an average on more points, you’ll remove even more of the noise. The orange one does represent an average on 60 points so a mobile average of 1h:

    image

    The period you have to choose depend on the quality of the signal and of course the change of data you still want to measure. The longest the period is and the less changes you can evaluate. So let use this last example with a 1 hour filter and let see if we can read anything on it. I know what was the weather and when I did sprinkler. Logically, each time it has rain, the signal should increase and decrease with no rain and high temperatures. And it should also increase if I did sprinkler. On this graph, I’ve put in red when it did rain and in green when I did sprinkler.

    image

    So even if we have this 60 points mobile filter and this remove rapid change in the measurement, it is still possible to see the impact of a rain or of a sprinkler. Now, I’ve added a 600 points mobile average and I let the pic where they were, here is the result:

    image

    it is still readable but the impact of an event can be read later. And the pic are lower. I don’t want to enter in the theory but to be simple, it’s just because, you are using more data, so as explain, the average will lower the result as it is there to remove high frequencies. And you’ll need more “higher” data to see an impact. It’s like if you had a field of green grass and add couple of red flowers. Take a picture and do an average of the color. It will be green. Add couple of other red flours, take a picture again, do the average and continue like this. And you’ll need to have lots of red flours added to see a change while you’ve started adding flowers some time ago. This is exactly what is happening there. You will detect the phenomenon much later than it happened.

    So if you want to use those kind of filters, make sure you use them wisely and not with a too long period. In my case, I will probably use for production something between 15 and 60 points. I need to have an idea of the humidity, not a very precise value. And as shown in the previous graph, it is visible when there’s been some rain or if the sprinkler was on.

    And of course, I’ll need also to work on the isolation of the cable to try to remove some of the noise.

    You may Wonder how I was able to log 19000 points? Well, it is very simple and the code is there:

    class LogToFile
    {
        static public bool Print(string StrFileName, string strToLog)
        {
            try
            {
                FileStream fileToWrite = new FileStream(StrFileName, FileMode.OpenOrCreate, FileAccess.Write);
                byte[] buff = Encoding.UTF8.GetBytes(strToLog);
                fileToWrite.Seek(fileToWrite.Length, 0);
                fileToWrite.Write(buff, 0, buff.Length);
                fileToWrite.Close();
                return true; 
            }
            catch (Exception e)
            { 
                return false;  
            }
        
        }
    }
    

    It takes a simple file name as an input and something to write. The code is straight forward, it first create or open a file. Then encode the string to write in the buff variable. Seek to the end of the file, write the buff and close the file. So extremely simple code!

    LogToFile.Print("WINFS\\out.txt", DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + ";" + mSensor.Humidity + "\r\n");
    

    And the usage is as simple as the code, one line to log data like in this example. and as a result, you get data like this in the text file:

    07/29/2012 13:34:46;86
    07/29/2012 13:34:47;93
    07/29/2012 13:34:48;91
    07/29/2012 13:34:49;93

    For the next article, we will see how to implement the filter in the real code.

  • Laurent Ellerbach

    A soil low cost humidity sensor (moisture) and .NET Micro Framework (NETMF)

    • 0 Comments

    I’m working on my own sprinkler system which I can pilot thru Internet wherever I am. I can add programs and also open and close sprinklers when I want. I recently build a prototype of a humidity sensor. Now it’s time to implement this humidity sensor in pre production and see how it is working for real. Next phase will be an automatic piloting based on this humidity sensor. Thanks also to all the feedback I get which encourage me to continue those posts. I’m just a marketing guy doing hardware and software development Sourire

    Based on the work of the prototype, I’ve build a normal size sensor and put it for real in my garden:

    WP_000846

    It is the same principle as the prototype, there are 2 coppers cables put in the soil (approx. 10 centimeters) and current arriving to those 2 cables. The potential is measured and interpreted to see how humid it is. To summarize, the more humid it is the lower the resistance of the soil is. So I need 3 cables only: one for ground, one for +3.3V and one for the measurement. I can chain sensors and will only need 1 additional cable per sensor. This solution is very simple and very easy to implement. There are smartest way to do this with a real serial bus self powered. But for the moment, I’m fine with this solution. I will explore the other solution when I will want to add temperature, luminosity and others like wind.

    Now, looking at the code, I wanted to make part of the code reusable and I’ve define a humidity sensor with simple Properties and a class to initialize the analogic input.

    public struct HumiditySenrorParam
    {
        public int MinValue;
        public int MaxValue;
        public int DeclValue;
        public int UpdateTime;
    }
    
    public class HumiditySensor
    {
        private SecretLabs.NETMF.Hardware.AnalogInput HumSensor;
        private Timer MyTimer;
        private int myDeclUpdate;
        private int myHumidity;
        private bool bhumid = false;
       
        public HumiditySensor(Cpu.Pin HumidityPin, 
    HumiditySenrorParam MyHumidityStruct) { if (!Microsoft.SPOT.Hardware.SystemInfo.IsEmulator) HumSensor =
    new SecretLabs.NETMF.Hardware.AnalogInput(HumidityPin); MyTimer = new Timer(new TimerCallback(ClockTimer_Tick),
    this, MyHumidityStruct.UpdateTime * 1000, 0); MinValue = MyHumidityStruct.MinValue; MaxValue = MyHumidityStruct.MaxValue; DeclValue = MyHumidityStruct.DeclValue; UpdateTime = MyHumidityStruct.UpdateTime; }

    The HumiditySensorParam class is used to pass the initialization value to the HumiditySensor class. Each class is using an analogic input on a specific Pin from the CPU. This value is also passed in the constructor.

    An analogic input on the netduino has 1024 points from 0 to 3.3V starting from 0 to 1023. But as explained in the previous article on the prototype, only part of this range is used. So I’m using 3 parameters: a minimum value, a maximum value and a value to determine the limit between dry and humid. All should be from 0 to 1023. It is not checked in the class but a good programmer will do Sourire

    Also, the analogic input has to be read in a regular timeframe. This is done by the UpdateTime value in seconds. A timer is raised every period to update the value of the humidity sensor.

    public int MinValue
    { get; set; }
    
    public int MaxValue
    { get; set; }
    
    public int DeclValue
    { get; set; }
    
    public int UpdateTime
    {
        get { return myDeclUpdate; }
        set
        {
            MyTimer.Change(0, value * 1000);
            myDeclUpdate = value; 
        }
    }
    

    All 4 parameters are stored into Properties. The min, max and decl value are stored in normal Properties. The UpdateTime is a bit different. It has to change the value of the timer. Again, here, I do things in a simple way, but all those values should be checked before setting them.

    Now let have a look at the timer

    static void ClockTimer_Tick(object sender)
    {
        HumiditySensor mSensor = (HumiditySensor)sender;
        mSensor.Update();
        //Debug.Print(DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") 
    + " Humidity: " + mSensor.Humidity + " IsHumid: " + mSensor.IsHumid);
    }

    The code is quite simple, it first get the object. This function must be a static one as it is called by .NETMF when it is time. The sender object is the humidity sensor itself as setup in the constructor. After the cast, it is possible to call the update method.

    public void Update()
    {
        if (!Microsoft.SPOT.Hardware.SystemInfo.IsEmulator)
            Humidity = HumSensor.Read();
        else
            Humidity = new Random().Next(MaxValue);
    }
    
    

    I first check if we are in the emulator or on a real Platform. In the case I’m in the emulator, I just return a random number. This allow to test the software when I do development in planes like now on my way to Atlanta Clignement d'œil

    In the other case, I read the analogic input and put the value into the Humidity property.

    public int Humidity
    { get {
        return myHumidity;
    }
        internal set {
            if (value < MinValue) value = MinValue;
            if (value > MaxValue) value = MaxValue;
            if (value >= DeclValue) bhumid = true; else bhumid = false;
            myHumidity = 100 * (value - MinValue)/(MaxValue - MinValue);} 
    }
    

    I allow to update this property only internally. I do the math with the Min, Max values to compute a percentage. And check if it is dry or humid.

    And I’ve also created 2 other Properties I can use later in the code:

    public bool IsHumid
    {
        get
        { return bhumid; }
    }
    
    public int DeclHumidity
    { 
        get { return (100 * (DeclValue - MinValue) / (MaxValue - MinValue)) ; }
    }
    

    The IsHumid return true if it is humid compare to the level and the DeclHumidity return this level in percentage.

    Here it is, you have a humidity sensor and the code to read the values Sourire Now we will look at how to use it. For this, I display the humidity level in the main web page with the information regarding the sprinklers. And I’ve also build a page to be able to change dynamically the values of the Humidity sensor. This is useful when you need to calibrate it.

    HumiditySenrorParam MyHumidityStruc = new HumiditySenrorParam();
    MyHumidityStruc.MinValue = 0;
    MyHumidityStruc.MaxValue = 1023;
    MyHumidityStruc.DeclValue = 500;
    MyHumidityStruc.UpdateTime = 60;
    
    Sprinklers[0].HumiditySensor = new HumiditySensor(Pins.GPIO_PIN_A0, MyHumidityStruc);
    

    Nothing complex in this initialization phase. I’ve already explained in previous posts the Sprinkler class. I just added a HumiditySensor member. So I can have 1 humidity sensor per sprinkling zone. Looking at how it’s working in the industry. And I want to be flexible. So I can have a humidity sensor wherever I want. I’m using a parameter file which I read and interpret at boot time.

    The final result looks like this with 1 humidity sensor:

    image

    And the code to build the page is easy:

    strResp = "<HTML><BODY>netduino sprinkler<p>";
    // need to test!
    strResp = WebServer.OutPutStream(response, strResp);
    for (int i = 0; i < NUMBER_SPRINKLERS; i++)
    {
        strResp += "Springler " + Sprinklers[i].Name + ": <a href='/" 
    + paramPageSprinkler + ParamStart + securityKey + ParamSeparator
    + paramSpr + i + ParamEqual + !Sprinklers[i].Open + "'>"
    + Sprinklers[i].Open + "</a><br>"; strResp += "<a href='/" + paramPageCalendar + ParamStart
    + securityKey + ParamSeparator + paramYear + ParamEqual + DateTime.Now.Year
    + ParamSeparator + paramMonth + ParamEqual + DateTime.Now.Month
    + ParamSeparator + paramSpr + ParamEqual + i + "'>Program Sprinkler "
    + Sprinklers[i].Name + "</a><br>"; strResp += "<a href='/" + paramPageListPrgm + ParamStart
    + securityKey + ParamSeparator + paramSpr + ParamEqual + i
    + "'>List all programs for Sprinkler " + Sprinklers[i].Name + "</a><br>"; if (Sprinklers[i].HumiditySensor != null) { strResp += "Humidity: " + Sprinklers[i].HumiditySensor.Humidity; if (Sprinklers[i].HumiditySensor.IsHumid) strResp += " and it is humid<br>"; else strResp += " and it is time to sprinkle!<br>"; } strResp = WebServer.OutPutStream(response, strResp); } strResp += "<p><a href='/" + paramPageUtil + ParamStart
    + securityKey + ParamSeparator + paramClk + ParamEqual
    + "1'>Update date and time</a><br>"; strResp += "<p><a href='/" + paramPageUtil + ParamStart
    + securityKey + ParamSeparator + paramReboot + ParamEqual
    + "1'>Reboot</a><br>"; strResp += DateTime.Now.ToString(); strResp += "</BODY></HTML>"; strResp = WebServer.OutPutStream(response, strResp);

    ParamStart = ‘?’, ParamSeparator = ‘&’, ParamEqual = ‘=’, the various paramPage are the name of the page (like “spr.aspx” for paramPageSprinkler). It is mainly about building and URL like spr.aspx?sec=seckey&spr0=True

    I display only the information regarding a humidity sensor if one has been setup. If not, I don’t display anything. And as you can see, it is really simple, the Humidity property return the humidity in percentage. and IsHumid allow to check if it is dry or humid so if it time to sprinkle or not Sourire

    You’ve read this blog post up to this point. So I’m sure you still have energy! I’ve build a page to be able to update the various parameters. The page look like this with one humidity sensor. With multiple humidity sensor, it will just display more forms on the same page:

    image

    When updates, the result is the following:

    image

    My code allow also to get this information without and UI, just with the data. It allow also to just change one sensor and not all. I will not show all the code, I will just explain the core part with the forms:

    for (int i = 0; i < NUMBER_SPRINKLERS; i++)
        if (Sprinklers[i].HumiditySensor != null)
        {
            //display a form with all params to be modified
            strResp += "<form method=\"get\" action=\"" 
    + paramPageHumidity + "\"><p>Humidity sensor "
    + Sprinklers[i].Name; strResp += "<br />Humidity = "
    + Sprinklers[i].HumiditySensor.Humidity + " and is Humid = "
    + Sprinklers[i].HumiditySensor.IsHumid + "<br />"; strResp += "Min = <input type=\"text\" name=\""
    + paramHumidityMinValue +"\" value=\"" + Sprinklers[i].HumiditySensor.MinValue
    + "\" /><br />"; strResp += "Max = <input type=\"text\" name=\""
    + paramHumidityMaxValue +"\" value=\"" + Sprinklers[i].HumiditySensor.MaxValue
    + "\" /><br />"; strResp += "Decl = <input type=\"text\" name=\""
    + paramHumidityDeclValue +"\" value=\"" + Sprinklers[i].HumiditySensor.DeclValue
    + "\" /><br />"; strResp += "Time update (sec) = <input type=\"text\" name=\""
    + paramHumidityTimeUpdate +"\" value=\""
    + Sprinklers[i].HumiditySensor.UpdateTime + "\" /><br />"; strResp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input id=\"Submit\" type=\"submit\" value=\"Update\" /></p>"
    ; strResp += "<input type=\"hidden\" name=\""
    + paramSpr + "\" value=\"" + i + "\">"; strResp += "<input type=\"hidden\" name=\""
    + paramSecurityKey + "\" value=\"" + MySecurityKey + "\"></form>"; strResp += "<br />"; strResp = WebServer.OutPutStream(response, strResp); }

    Nothing really complicated here, it’s just building a HTML page by hands Sourire The form will be posted with the GET method. So all parameters will be passed thru the URL. I’ve used this method for all the development I’ve done and you’ll find examples in my previous posts. Including the web server itself.

    So enjoy this humidity sensor Sourire And I hope the weather will get dryer in Paris this summer so I’ll be able to calibrate it correctly, find the right level Under which it is interesting to sprinkle. And of course, next step is to automate all this! And let the system manage itself based on the soil humidity. And I will add other sensors like temperature! Stay tune Sourire and feedback welcome as usual.

  • Laurent Ellerbach

    A low cost humidity sensor for my sprinkler system

    • 0 Comments

    I’ve developed my own sprinkler system which embed a web server and allow me to control it remotely where ever I am. I can program when and how long I will sprinkler on which circuit. I have 3 circuits but my system can work with a large number of circuits.

    What I want to do is to be able to add intelligence into my netduino board. This .NET Microframework (NETMF) board runs without any OS. So now Windows, no Linux, no Mac, nothing! Directly .NET on the chip. Not a full .NET of course but all what is necessary to be able to pilot IO, have a web server, etc. All this in an embedded board smallest of the size of a credit card.

    Part of my project is to be able to measure the soil humidity. So I’ve decided to develop my own sensor. The basic idea is to measure the conductivity (or resistor) of the soil. Any object/material has it’s own resistance. The more conductive it is, the smallest the resistor is and the less conductive, the higher the resistor is. And it does apply to anything. Metals are usually excellent resistors with a very low resistance of less than 1 Ω. And something like a plastic will have more than 1 MΩ resistor. So if you apply a huge voltage, you’ll get a very small current.

    The rule you have to know to do some electronic is U = R x I where U is the voltage (tension in volt V), R is the resistor (in ohm Ω) and I is the intensity of the current (in ampere, A). So I will measure the resistor 'of the soil and I will determine if it is dry or humid.

    Let start wit a bit of theory there regarding soil conductivity. It is possible to measure the soil conductivity with a Tellurometer. Soil conductivity is measured by this specific sensor and the resistance of the soil is determined. In my case what will interest me is to be able to measure the difference of conductivity between a humid and a dry soil at the same place. It just need to have 2 stick of copper or any other metal put into the soil and have a current going thru one stick and measuring the difference of voltage from the other.

    When a soil is humid the resistor decrease and when it is dry, it does increase. So imagine I will build something like a voltmeter put into the soil and I will measure the resistance. As my netduino has an analogic input I will use it for this purpose. What I measure here, is a voltage so indirectly this variance or resistance. As per the light sensor, I’ll use the same principle:

    image

    So I will measure the voltage of R3. R3 is a high value of 10K to do a pull down. It is a high resistor which will create a small current between the ground and A0. If I don’t put any resistor,I won’t be able to measure any intensity. And if I place A0 on the ogher side of my sensor and remove R3, I will use more current than in this design. It is possible to do the same as for the light sensor but in my case it will be a bit less efficient I guess.

    R1 is here to reduce a bit the current and I will have to adjust this value regarding of my current soil.

    The code is extremely simple:

    SecretLabs.NETMF.Hardware.AnalogInput SoilSensor =
    new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0); //lightSensor.SetRange(0, 100); int lSoilSensorReading = 0; while (true) { SoilSensorReading = SoilSensor.Read(); Debug.Print(SoilSensorReading.ToString()); Thread.Sleep(500); }

    I create an analogic input on port A0. And then I read the value every 500 milliseconds. And that’s it!

    I’ve done the test with real soil, one is very humid, one a bit humid and one is very dry.

    I get the following results:

    • very humid = 650
    • a bit humid = 630
    • very dry = 550

    And here is the picture of the prototype:

    WP_000792 

    As the analogic port has 1024 values going from 0 to 1023 on 3.3V, I have an amplitude of 100 values which represent a variance of approximately 0.32V.

    So with this prototype I have a difference of 0.32V between dry and very humid with this specific soil.

    I’m sure I can change a bit the sensitivity to use a broader range of the analogic input. I can do like for the light sensor an remove the R3 resistor and measure directly the tension between the sensor and the ground. I can also change R1 to a value close to the middle of the resistance of the soil. I can also change the alimentation value to 5V or so.

    That was just a first experiment! Just to prove it is working Sourire Now, I need to improve a bit the system and see how far I can go. Any feedback from an electronic guy welcome.

  • Laurent Ellerbach

    Using XMLHttpRequest to pilot a Lego train dynamically in HTML 5

    • 4 Comments

    It’s a long time I did not write a blog post. I was very busy and had no time to write and code anything in the last weeks. I still have a lot of work but I need an intellectual break for the evening. So I do not write this post from a plane but from an hotel room. In my past blog posts I’ve explained how to pilot any Lego Power System with a Netduino using .NET Microframework.

    In the HTTP Web server I’ve implemented, I command the train thru a URL with arguments. Those arguments are transformed into parameters which are given to a class. This class output a wave form into an infrared led amplified by a transistor. This is a simple and efficient way to command anything. I do the same for my sprinkler system.

    Now if you want to pilot in a web interface multiple trains, and click on buttons or pictures to get an action without opening a new web page or refreshing the page, you need to do some Scripting in your HTML page. I’m not a web developer, I don’t like Scripting languages as they are not strict enough to write correct code and imply too many errors. They drastically increase your development time! I truly prefer a good language like C#, VB or even Java and I can go up to C/C++ Sourire Now, if I want to avoid any problem, I can jump into Eiffel Sourire OK, I won’t go up to there, I’ll stay with java script in an HTML5 page.

    What I want is to call my command page in the background of the page and stay in the HTML page when I click on a button. There is a nice object in HTML which allow you to do that which is XMLHttpRequest. It is implemented in all decent browsers.

    Here is the code that I generate dynamically (I’ll show you the code later) and I’ll explain you how it works:

    <html xmlns="http://www.w3.org/1999/xhtml"><head>
    <title></title></head><body>
    <SCRIPT language="JavaScript">
    var xhr = new XMLHttpRequest();
    function btnclicked(boxMSG, cmdSend) {
        boxMSG.innerHTML = "Waiting";
        xhr.open('GET', 'singlepwm.aspx?' + cmdSend + '&sec=');
        xhr.send(null);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4)
            { boxMSG.innerHTML = xhr.responseText; } 
    };
    }
    </SCRIPT>
    <TABLE BORDER="0"><TR><TD>
    <FORM>Super train</TD><TD>
    <INPUT type="button" 
    onClick="btnclicked(document.getElementById('train0'),
    'pw=11&op=0&ch=254')" 
    value="<"></TD><TD>
    <INPUT type="button" 
    onClick="btnclicked(document.getElementById('train0'),
    'pw=8&op=0&ch=254')" value="Stop"></TD><TD>
    <INPUT type="button" 
    onClick="btnclicked(document.getElementById('train0'),
    'pw=5&op=0&ch=254')" value=">"></TD><TD>
    <span id='train0'></span></FORM></TD></TR>
    
    

    In the script part of the page, I have created a simple script. Those lines of code is what is necessary to do a synchronous call of an HTTP page and display the result in the page.

    I create an XMLHttpRequest object which I call xhr. The function call btnclicked takes 2 arguments. the first one is the element of the page I will put the results of the request. And the second one is the command (the parameters) to pass to the URL which will pilot the infrared led as explain previously.

    The function is very simple. First, I put “Waiting” in the element. Then I open the XMLHttpRequest object. I open it with GET and pass the overall URL.

    The request is done when the send function is called. It is a synchronous call, so it get to the onreadystatechange when it is finished.

    Here, when you read the documentation, the readyState 4 mean that everything went well and you have your data back. My function return “OK” when everything is OK and “Problem” if there is a problem.

    Now let have a look at the rest of the HTML page. I decided to create a form with button input. Each button input has a onClick event. This event can be linked to a script. So I will call the fucntion describe before and give a span element (here train0) and the URL. The URL is different depending if you want to train to go forward, backward or stop. And I put all this in a nice table top be able to have multiple trains.

    The page with 4 trains looks like this:

    image

    I’ve clicked on the forward button, “Wainting” is displayed in span. And as soon as the command will finish, it will either display OK or Problem. In my case, Problem will be displayed as in the Emulator, there is no SPI port!

    // Start HTML document
    strResp = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"
    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
    ; strResp += "<html xmlns=\"http://www.w3.org/1999/xhtml\">
    <head><title></title></head><body>"
    ; //creat the script part strResp += "<SCRIPT language=\"JavaScript\">"; strResp += "var xhr = new XMLHttpRequest(); function btnclicked(boxMSG, cmdSend)
    { boxMSG.innerHTML=\"Waiting\";"
    ; strResp += "xhr.open('GET', 'singlepwm.aspx?' + cmdSend + '&" + securityKey + "');"; strResp += "xhr.send(null); xhr.onreadystatechange = function()
    {if (xhr.readyState == 4) {boxMSG.innerHTML=xhr.responseText;}};}"
    ; strResp += "</SCRIPT>"; strResp = WebServer.OutPutStream(response, strResp); // Create one section for each train strResp += "<TABLE BORDER=\"0\">"; for (byte i = 0; i < myParamRail.NumberOfTrains; i++) { strResp += "<TR><TD><FORM>" + myParamRail.Trains[i].TrainName + "</TD>
    <TD><INPUT type=\"button\"
    onClick=\"btnclicked(document.getElementById('train"
    + i + "')
    ,'pw="
    + (16 - myParamRail.Trains[i].Speed); strResp += "&op="+ myParamRail.Trains[i].RedBlue + "&ch=" +
    (myParamRail.Trains[i].Channel - 1) + "')\" value=\"<\"></TD>"; strResp += "<TD><INPUT type=\"button\"
    onClick=\"btnclicked(document.getElementById('train"
    + i + "'),'pw=8"; strResp += "&op=" + myParamRail.Trains[i].RedBlue + "&ch=" +
    (myParamRail.Trains[i].Channel - 1) + "')\" value=\"Stop\"></TD>"; strResp += "<TD><INPUT type=\"button\"
    onClick=\"btnclicked(document.getElementById('train"
    + i + "'),
    'pw="
    + myParamRail.Trains[i].Speed; strResp += "&op=" + myParamRail.Trains[i].RedBlue + "&ch=" +
    (myParamRail.Trains[i].Channel - 1) + "')\" value=\">\"></TD>"; strResp += "<TD><span id='train" + i + "'></span></FORM></TD></TR>"; strResp = WebServer.OutPutStream(response, strResp); } strResp += "</TABLE><br><a href='all.aspx?" + securityKey +
    "'>Display all page</a>"; strResp += "</body></html>"; strResp = WebServer.OutPutStream(response, strResp);

    The code to generate the HMTL page is here. As you see it is manually generated. The table which contains the name of the train, the backward, stop and forward button is created totally dynamically. Each train may have a different speed and use different channels so the URL is generated dynamically.

    All this takes time to generate and to output in the Stream. So it’s much better to do it only 1 time and then call a simple and small function which will return just a bit of text.

    Last part, on the server header, you have to make sure you add “Cache-Control: no-cache” in the response header. If you don’t do it, only the first request will be send to the netduino board back. XMLHttpRequest will consider that the page will never expire. So I’ve modified the header code of my HTTP Server like this:

    string header = "HTTP/1.1 200 OK\r\nContent-Type: text/html; 
    charset=utf-8\r\nCache-Control: no-cache\r\nConnection:
    close\r\n\r\n"
    ; connection.Send(Encoding.UTF8.GetBytes(header), header.Length,
    SocketFlags.None);

    What is interesting there is that I can now pilot up to 8 Lego trains using this very simple interface and without having to refresh the page.

    And the excellent news is that it is working from my Windows Phone so it’s even cool to pilot your Lego train from your Windows Phone. I haven’t tested from an Android or iPhone but I’m quite sure it will work the same way. Remember that all the code is sitting in a very small hardware with no OS, just .NET Microframework! As always, do not hesitate to send me your comments Sourire

  • Laurent Ellerbach

    Creating an efficient HTTP Web Server for .NET Microframework (NETMF)

    • 4 Comments

    That’s not the first post I’m doing on incorporating a Web Server in .NET Microframework (NETMF). In some of my previous posts, I’ve explain how to do it using the existing .NET classes for this. And it is working very well!

    The main concerns I have is that I’m using a netduino board. This board is great, I love it. But there is a very limited amount of memory available and limited amount of space to store the programs. Total storage is 64Kb and what is left when the code is in is about 48K… So very little amount of memory. And the http .NET classes are great and use stream but they are intense in terms of memory and also the main http class is huge…

    So I had to find a solution and it was to redevelop a web server like IIS or Apache. OK, I can’t compare Sourire I just want a web server which handle GET answers and respond a simple web page. The other challenge I have is to be able to reuse the code I4ve already written for my Sprinkler, to pilot my Lego city and my Lego infrared receiver like my Lego trains…

    So I was searching for code to reuse on the Internet and found some code. So I did a mix of existing code and spend some time testing various solutions Sourire Most of the existing code is not really robust. It does fail if there is a network problem, if 2 requests arrive at the same time, etc. I’m not saying my code is perfect but it is working and working well for the last month with no problem at all.

    A web server is simple, it’s just a connection on a socket and a protocol of communication which is HTTP. It is also very simple as it is text based. What is interesting is to see all what you can do with such a simple protocol and such a simple markup language like HTML and some javascript.

    OK, so let start with what is necessary: a thread that will run all the time and handle socket requests. So we need also a socket. And a way to stop the thread.

     
    private bool cancel = false;
    private Thread serverThread = null;
    
    public WebServer(int port, int timeout)
    {
        this.Timeout = timeout;
        this.Port = port;
        this.serverThread = new Thread(StartServer);
        Debug.Print("Web server started on port " + port.ToString());
    }
    

    As you can see, it is quite simple, the WebServer object is initialize with a specific port and a timeout. By default, the http port is 80 but it can be anything. There is no limitation. And as it’s easy to implement, let make the code generic enough to be able to be use with different ports. And a new Thread is created to point on function StartServer. I will detail it later. I will explain also why we need a timeout later.

    Now we have this object initialize, let start the Webserver:

    public bool Start()
    {
        bool bStarted = true;
        // start server           
        try
        {
            cancel = false;
            serverThread.Start();
            Debug.Print("Started server in thread " + serverThread.GetHashCode().ToString());
        }
        catch
        {   //if there is a problem, maybe due to the fact we did not wait engouth
            cancel = true;
            bStarted = false;
        }
        return bStarted;
    }
    
    
    
    

    That is where the fun being! We start listening and initialize a variable we will use later to stop the server if needed. The catch can contain something to retry to start, here, it just return if it is started or not. At this stage, it should work with no problem as it is only a thread starting. But who knows Sourire

    private void StartServer()
    {
        using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            //set a receive Timeout to avoid too long connection 
            server.ReceiveTimeout = this.Timeout;
            server.Bind(new IPEndPoint(IPAddress.Any, this.Port));
            server.Listen(int.MaxValue);
            while (!cancel)
            {
                try
                {
    
                    using (Socket connection = server.Accept())
                    {
                        if (connection.Poll(-1, SelectMode.SelectRead))
                        {
                            // Create buffer and receive raw bytes.
                            byte[] bytes = new byte[connection.Available];
                            int count = connection.Receive(bytes);
                            Debug.Print("Request received from " 
    + connection.RemoteEndPoint.ToString() + " at " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss")); //stup some time for send timeout as 10s. //necessary to avoid any problem when multiple requests are done the same time. connection.SendTimeout = this.Timeout; ; // Convert to string, will include HTTP headers. string rawData = new string(Encoding.UTF8.GetChars(bytes)); string mURI; // Remove GET + Space // pull out uri and remove the first / if (rawData.Length > 5) { int uriStart = rawData.IndexOf(' ') + 2; mURI = rawData.Substring(uriStart, rawData.IndexOf(' ', uriStart) - uriStart); } else mURI = ""; // return a simple header string header = "HTTP/1.1 200 OK\r\nContent-Type: text/html
    ; charset=utf-8\r\nConnection: close\r\n\r\n"
    ; connection.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None); if (CommandReceived != null) CommandReceived(this, new WebServerEventArgs(connection, mURI)); } } } catch (Exception e) { //this may be due to a bad IP address Debug.Print(e.Message); } } } }

     

    This function will run all the time in a thread. It’s in an infinite loop which can be break by the cancel variable. First, we need to initialize the Socket. We will use IPv4 with a stream and the TCP protocol. No timeout to receive the request. The, you’ll have to bind this socket to a physical IP address. In our case, we will use all IP address on the port initialized before. Any IP address mean all addresses and in our case only 1 IP address as we do have only 1 Ethernet interface. We are using '”using” to make sure the server Socket will be closed and cleaned properly after usage.

    The way it is working is not too complicated. Remember that we’ve open a Socket named Server, setup it to listen to port 80. This is running in a separate thread in this thread. So in order to analyze the information returned when a connection is accepted (so when a Browser ask for a page), we need to create another Socket pointing to the same Socket, here “using (Socket connection = server.Accept())”. In this case “using” allow the code to clean in the “proper way” when the thread will be finished or then the loop end or when it goes back to the initial loop. It’s thread in thread and if you don’t close things correctly, it can quickly let lots of objects in the memory, objects which will be seen as alive by the garbage collector.

    When there are bytes ready to read with connection.Poll, we just read them. The request is transformed into a string. An http request look like “GET /folder/name.ext?param1=foo&param2=bar HTTP/1.1”. Areal life example looks more like this: "GET /folder/name.ext?param1=foo&param2=bar HTTP/1.1\r\nAccept: text/html, application/xhtml+xml, */*\r\nAccept-Language: fr-FR,fr;q=0.8,en-US;q=0.5,en;q=0.3\r\nUser-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)\r\nAccept-Encoding: gzip, deflate, peerdist\r\nHost: localhost:81\r\nConnection: Keep-Alive\r\nX-P2P-PeerDist: Version=1.1\r\nX-P2P-PeerDistEx: MinContentInformation=1.0, MaxContentInformation=1.0\r\n\r\n"

    For a normal, full web server like IIS or Apache, you’ll analyze all those parameters, and there are lots, see the W3C protocol here. For our usage, the only thing that interest us is the full URL. And it is located between the 2 first spaces. And we will extract the URL, remove the first ‘/’ as I will not use it in the rest of the code.

    Now, the next step is to start answering the request. When someone ask you something, it’s polite to answer Sourire Like for the request, the response need to have couple of header information. And as my usage is extremely simple, I will always consider that it is OK, I’m only delivering text content and that the connection can be closed. By the way, whatever you put there, HTTP is a disconnected protocol, so you should never consider that you are always connected! It’s an error and can drive you to very bad behaviors.

    connection.Send return the first part of the message and then I call an event to tell the creator of the WebServer object that something happened. I send of course the connection object so that the caller will be able to create an HTML page and answer and also the URL so that it can analyze it.

    Last but not least, the try and catch is extremely important. With Sockets a problem can quickly arrive due to a network problem. And I’ve seen it happening on the netduino for no reason. Just capturing the problem and not doing anything makes the web server working for months! Even if you loose the network, the catch will capture the problem and the server will continue to work up to the point the network will work again. The other reason to use it is because of the timeout. If something happen between the client and our webserver, after the timeout, you’ll get in this catch and you’ll start a new socket and the process will go back to something normal. It can happen and happened to me with very long HTML pages I was generating. When I was interrupting the creation and ask for a new page, the socket went into a kind of infinite loop waiting for a request. There should be a smart way to check is something goes well or not but it’s an easy way.

    public delegate void GetRequestHandler(object obj, WebServerEventArgs e);
    public class WebServerEventArgs: EventArgs
    {
        public WebServerEventArgs(Socket mresponse, string mrawURL)
        {
            this.response = mresponse;
            this.rawURL = mrawURL;
        }
        public Socket response { get; protected set;  }
        public string rawURL { get; protected set; }
    
    }
    
    public event GetRequestHandler CommandReceived;
    

    Right after the header is sent back, an event is raised. The arguments are simple here, we do send the Socket object and the URL. If you want to enrich the web server, you can add other elements like the header element rather than sending them right away, the browser requesting the page, the IP address or whatever you want! Again, simple and efficient there.

    Last but not least if you need to stop the Server, you’ll need a function to this and also to clean the code at the end:

    private bool Restart()
    {
        Stop();
        return Start();
    }
    
    public void Stop() { cancel = true; Thread.Sleep(100); serverThread.Suspend(); Debug.Print("Stoped server in thread "); }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            serverThread = null;
        }
    }
    

    Nothing too complex there, it’s just about pausing the thread (remember, there are other tread attached in it), closing the other thread leaving in the Server object and cleaning everything. I hope it’s the good code to let it clean Sourire But at the end of the day, my only interest is to let this server running all the time. So I don not really care if it will stop correctly!

    Now, to use the server, easy:

    private static WebServer server;
    
    // Start the HTTP Server
    
    WebServer server = new WebServer(80, 10000);
    server.CommandReceived += new WebServer.GetRequestHandler(ProcessClientGetRequest);
    // Start the server.
    server.Start();
    

    Declare a static WebServer if you want it to be unique. Technically, you can have multiple servers running on different port. In my case, no need for this. Then, it’s about creating the object, adding an event and starting the server!

    private static void ProcessClientGetRequest(object obj, WebServer.WebServerEventArgs e)
    

    And you are ready to do some treatment into this function. To return part of the answer, just use e.response.Send as for the header part and you’re done!

    To simplify the process, as it’s a function which you’ll have to call often, I’ve created a function to do this:

    public static string OutPutStream(Socket response, string strResponse)
    {
        byte[] messageBody = Encoding.UTF8.GetBytes(strResponse);
        response.Send(messageBody, 0, messageBody.Length, SocketFlags.None);
        //allow time to physically send the bits
        Thread.Sleep(10);
        return "";
    }
    

    This can be a function you add in your main code or can add in the Web Server code.

    Now you have a fully functional simple Web Server. You can read the previous article on how to handle parameters and analyzing them. The code to manage the parameter is now in the WebServer class.

    I’ll post the code in CodePlex so anyone will be able to use it as a helper.

    Enjoy this code Sourire Again, I’m just a marketing director doing some code. And it’s the code running in my sprinkler management system for the last month without any problem!

  • Laurent Ellerbach

    Using a SPI device with netduino and .NET micro framework

    • 0 Comments

    After playing with I2C, with various IO, I’ve decided to play a bit with SPI Sourire The real project behind using a SPI device is to be able to use it a a multiplexer/demultipler of IO.

    I want to pilot lights for my Lego train. The idea is to have the ability to switch a signal light to green or red. I want to be able to have 16 lights. The netduino board have only 14 digital IO and 6 analogic. And I’m already using some to pilot the Lego train thru infrared. See previous article.

    So I have to find a multiplexing solution. And one is used by most of the netduino fan: SPI. In terms of electronic it’s simple, it is a serial to parallel (and vice versa as you can read also). The component the most used for this is 74HC595. There are couple of basics explanations on the netduino wiki and also good examples as always on Mario Vernari blog.

    Each 74HC595 can have 8 output and they can be chained. Which mean that you can use 2 component to have 16 output. And you basically put them in series. One output of one 74HC595 to the input of the others.

    I spend quite a bit of time to understand how to plug the 74HC595 to the netduino. So here is what to do:

    • Pin 8 is ground
    • Pin 16 is VCC (+5V recommended)
    • Pin 14 to netduino pin D11 (called MOSI) for the first 74HC595 of the chain. For the next one it has to be linked to the Pin 9 of the previous 74HC595
    • Pin 13 to ground (used to activate or not the 8 output)
    • Pin 12 to one output port you’ll choose on the netduino. Let say pin D10. This one is used to select the 74HC595 when you have multiple 74HC595 used in parallel for different purposes (called SS)
    • Pin 11 to netduino pin D13 (called SCLK)
    • Pin 10 to +VSS (this one is used to reset if needed)
    • Pin 15, 1, 2, 3, 4, 5, 6, 7 are the output pin
    • Pin 9 has to be linked to the next 74HC595 of the chain if there are more than 1.

    And that’s it for the basics! Now what I want to do with the output is to be able to light one led green or switch it to red. So I’ll use the output of the 74HC595. When it will be 1, I’ll light the green one, when it will be 0, I’ll light the red one. Here is the hardware to schematic:

    image

    When the signal will be 1, the current will go thru the green light light. And when it will be 0, the inverter will switch to 1 and the red light will light. It just need 3 cables per light and the current can be transported on long distance. The RS resistor can be adapted with a lower resistor to 100 or something like this in order to send a more intense current in the cable as there will be some loss if it is very long. by the way I recommend to read the excellent article on the length of cable and impact on signal noise from Mario.

    Now, in terms of software, It’s not so difficult. In my project, I’m using the SPI for multiple purpose. So I need to use it in a smart way. SPI can be shared and the only thing to do is to change the configuration and write (and read) right after. So I’m using the MultiSPI class from the NETMF Toolbox. It’s an impressive toolbox containing lots of helpers. It goes from hardware to HTTP web client. There is a 74HC595 also but I found it more complex to use that just directly using the MultiSPI class.

    Here the example of class to switch to green (1) or red (0) a specific output of the 2 74HC595:

    public class Signal
    {
        private byte mNumberSignal;
        private bool[] mSignalStatus;
        public const byte NUMBER_SIGNAL_MAX = 16;
        private MultiSPI MySignal;
    
        public Signal(byte NumberOfSignal)
        {
            mNumberSignal = NumberOfSignal;
            if ((mNumberSignal <= 0) && (mNumberSignal > NUMBER_SIGNAL_MAX))
                new Exception("Not correct number of Signals");
            mSignalStatus = new bool[mNumberSignal];
            // open a SPI
            MySignal = new MultiSPI(new SPI.Configuration(
                Pins.GPIO_PIN_D10, // SS-pin
                false,             // SS-pin active state
                0,                 // The setup time for the SS port
                0,                 // The hold time for the SS port
                false,              // The idle state of the clock
                true,             // The sampling clock edge
                1000,              // The SPI clock rate in KHz
                SPI_Devices.SPI1));   // The used SPI bus (refers to a MOSI MISO and SCLK pinset)
    
            //initialise all signals to "false"
            for (byte i = 0; i < mNumberSignal; i++)
                ChangeSignal(i, true);
        }
    
        public byte NumberOfSignals
        { get { return mNumberSignal; } }
    
        public void ChangeSignal(byte NumSignal, bool value)
        {
            if ((NumSignal <= 0) && (NumSignal > mNumberSignal))
                new Exception("Not correct number of Signals");
            //need to convert to select the right Signal
            mSignalStatus[NumSignal] = value;
            // fill the buffer to be sent
            ushort[] mySign = new ushort[1] { 0 };
            for (ushort i = 0; i < mNumberSignal; i++)
                if (mSignalStatus[i])
                    mySign[0] = (ushort)(mySign[0] | (ushort)(1 << i));
            //send the bytes
            MySignal.Write(mySign);
            
    
        }
    
        public bool GetSignal(byte NumSignal)
        {
            if ((NumSignal <= 0) && (NumSignal > mNumberSignal))
                new Exception("Not correct number of Signals");
            return mSignalStatus[NumSignal];
        }
    }
    

    I just need to declare a MultiSPI. The SPI Configuration contains the necessary information to setup the 74HC595. The SS pin is set to D10. So I can use the SPI for other purposed to pilot my Lego infrared modules. And in the Lego module, I’ll have also to declare the SPI as MultiSPI.

    What the MultiSPI class is doing is very simple. It has a static SPI in its private variables. And a SPI.Configuration which is not static.

    /// <summary>Reference to the SPI Device. All MultiSPI 
    devices use the same SPI class from the NETMF, so this reference is static
    </summary> private static SPI _SPIDevice; /// <summary>SPI Configuration. Different for each device, so not a static reference</summary> private SPI.Configuration _Configuration;
    // Store the configuration file for each MultiSPI instance
    Sets the configuration in a local value
    this._Configuration = config; // If no SPI Device exists yet, we create it's first instance if (_SPIDevice == null) { // Creates the SPI Device only 1 time as it is a static! _SPIDevice = new SPI(this._Configuration); }
    public void Write(byte[] WriteBuffer)
    {
        _SPIDevice.Config = this._Configuration;
        _SPIDevice.Write(WriteBuffer);
    }
    

     

    So each time a program want to write in a SPI, the right configuration is selected and the write command is send. It’s working like this to read. The full class is a bit more complex but the main principle is there.

    The rest of my code is very simple and I’m sure I would have been to write it in a better way. I’m just storing the state of a signal and then output all the buffer to the SPI.

    So bottom line, it is very easy to use SPI as a multiplexer/demultipler for IO. That was what I needed. I did not tested yet how to read the data but it should be as simple!

  • Laurent Ellerbach

    Managing my Sprinklers from the Cloud

    • 1 Comments

    I’ve started a project to pilot my sprinklers remotely and make them smart almost 9 months ago. The idea is to be able to remotely open and close my sprinklers but also be able to launch automatic sprinkling cycles.

    After some software and hardware development, I now have a fully working solution:

    WP_000611

    You can see the netduino .NET Microframework board where all the smart is happening. I wrote couple of articles already to show how to implement a web server, launch timers, create calendars, get the date and time. I’ve also wrote couple of articles on hardware.

    Recently, I’ve met with Alain, a Lego fan like me and I show him the way I can control any Lego Power Function element using .NET Microframework. And we discussed about my sprinkler project. I was about to implement the final solution with my existing 9V Gardena electro valves. And he challenged ma on this telling me that I will never know the status of the electro valve if I hacked the Gardena system. And he tell me to go for a 24V DC electro valve. The big advantage is that when you switch on the current, it open the valve, when it’s off, it close. So no unknown state like with the bistable  valve from Gardena. So I bought 3 24V DC electro valve for 22€ each plus couple of cents for the diode (never forget to add a return current diode on a solenoid Sourire).

    WP_000612

    And the display screen with the button you see is a Crouzet automate. It’s a gift from Alain and it’s really cool to have it. For my project, it can be replaced by 3 buttons, 3 leds and 3 transistors but it’s just more cool Sourire The netduino enter in the DC input section and when the voltage is higher than 2V (normal high level is 3.3V), it just switch on an electro valve. So nothing complicated there.

    What has been long is to bring electricity when I wanted this box to be plus networking plus bring cables to all the places where I have electro valves. And as I have in front and rear of the house, I have lots of cables to install nicely in the basement. And just this took 1 full day with a friend who helped me. Thanks Thomas by the way Sourire

    And now from my Windows Phone or a PC or any other device which support HTML, I can open, close and program my sprinklers:

    image

    I’m an happy geek Sourire And as there are always some improvement to do, next step is to add a I2C temperature sensor to get information on the temperature outside and implement automatic rules.

    Stay tune!

  • Laurent Ellerbach

    Using netduino and .NET Microframework to pilot any Lego Power Function thru Infrared (part 3)

    • 0 Comments

    In the previous post, I’ve explain how to create a class and the hardware that will be able to pilot any Lego Power Function. In this article, I will explain how to create a web server (like IIS or Apache but much much much more simpler) and create a simple way to call the class.

    I’ve already explained how to create such a web server into one of my previous article. So Il will use the same idea. I will only explain the implementation of the specific part to call the Combo Mode function as I already take it in the past articles.

    The function is part of the LegoInfrared class and looks like

    public bool ComboMode(LegoSpeed blue_speed, LegoSpeed red_speed, LegoChannel channel)
    

    LegoSpeed and LegoChannel are both enums.

    The simple view of the HTTPServer Class is the following:

    public static class MyHttpServer
    {
        const int BUFFER_SIZE = 1024;
        // Strings to be used for the page names
        const string pageDefault  = "default.aspx";
        const string pageCombo  = "combo.aspx";
        // Strings to be used for the param names
        const string paramComboBlue = "bl";
        const string paramComboRed = "rd";
        const string paramChannel = "ch";
        // Strings to be used for separators and returns
        const char ParamSeparator = '&';
        const char ParamStart = '?';
        const char ParamEqual = '=';
        const string strOK = "OK";
        const string strProblem = "Problem";
        
        // Class to be used to find the parameters
        public class Param
        // Create a Lego Infrared object
        private static LegoInfrared myLego = new LegoInfrared();
        public static void StartHTTPServer()
        {
            // Wait for DHCP (on LWIP devices)
            while (true)
            {
                IPAddress ip = IPAddress.GetDefaultLocalAddress();
    
                if (ip != IPAddress.Any) 
                {
                    Debug.Print(ip.ToString());   
                    break;
                }
    
                Thread.Sleep(1000);
            }
            
    
            // Starts http server in another thread.
            Thread httpThread = new Thread((new PrefixKeeper("http")).RunServerDelegate);
            httpThread.Start();
    
            // Everything is started, waiting for commands :-)
            Debug.Print("Everything is started, waiting for command");
        }
    

    There are of course couple of other functions part of the class but I make it simple here. I created couple of const to be able to handle the name of pages and as explained in past articles, I will use URL like combo.aspx?bl=8&rd=2&ch=1

    Here by convention, bl will contains the value of the blue speed, rd, the red one and ch the Channel. the combo.aspx is the page name to call the ComboMode function. And yes, I do not need to use any extention, I can use just combo? or cb? or whatever I want. But I feel it’s cool to see .aspx as an extension in a board with only couple of kb of memory Sourire

    Now let have a look at the ProcessClientGetRequest function which will allow us to switch from one page to another.

    private static void ProcessClientGetRequest(HttpListenerContext context)
    {
    
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;
    
        string strFilePath = request.RawUrl;
        // Switch to the right page 
        // Page Combo
        if (strFilePath.Length > pageCombo.Length)
        {
            if (strFilePath.Substring(1, pageCombo.Length).ToLower() == pageCombo)
            {
                ProcessCombo(context);
                return;
            }
         }
         // Brunch other pages + Start HTML document
    }
    

    This function is called when a GET request is done to the Web Server. The request.RawURL return the name of the URL with all the parameters. So we just need to compare the name of the page with the first part of the URL. All URL start with /, so we start at position 1. If it does match, then, go to the ProcessCombo function. Otherwise, continue and do switches like that for all needed pages. And finally, you can build your own code. And that is what we will do later. Yes, we will generate a bit of HTML Sourire

    private static void ProcessCombo(HttpListenerContext context)
    {
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;
        string strParam = request.RawUrl;
        string strResp = "";
        if (DecryptCombo(strParam))
            strResp = strOK;
        else
            strResp = strProblem;
        OutPutStream(response, strResp);
    }
    
    

    This function is very simple and just do a branch depending on the result of the DecryptCombo function. If it is successful, then it will return OK, if not, it will return Problem.

    private static bool DecryptCombo(string StrDecrypt)
    {
        // decode params
        Param[] Params = decryptParam(StrDecrypt);
        int mChannel = -1;
        int mComboBlue = -1;
        int mComboRed = -1;
        bool isvalid = true;
        if (Params != null)
        {
            for (int i = 0; i < Params.Length; i++)
            {
                //on cherche le paramètre strMonth
                int j = Params[i].Name.ToLower().IndexOf(paramChannel);
                if (j == 0)
                {
                    mChannel = Convert.ToInt32(Params[i].Value);
                    if (!((mChannel >= (int)LegoInfrared.LegoChannel.CH1)
    && (mChannel <= (int)LegoInfrared.LegoChannel.CH4))) isvalid = false; } j = Params[i].Name.ToLower().IndexOf(paramComboBlue); if (j == 0) { mComboBlue = Convert.ToInt32(Params[i].Value); if (!((mComboBlue == (int)LegoInfrared.LegoSpeed.BLUE_BRK)
    || (mComboBlue == (int)LegoInfrared.LegoSpeed.BLUE_FLT) || (mComboBlue == (int)LegoInfrared.LegoSpeed.BLUE_FWD)
    || (mComboBlue == (int)LegoInfrared.LegoSpeed.BLUE_REV))) isvalid = false; } j = Params[i].Name.ToLower().IndexOf(paramComboRed); if (j == 0) { mComboRed = Convert.ToInt32(Params[i].Value); if (!((mComboRed >= (int)LegoInfrared.LegoSpeed.RED_FLT)
    && (mComboRed <= (int)LegoInfrared.LegoSpeed.RED_BRK))) isvalid = false; } } } // check if all params are correct if ((isvalid) && (mComboRed != -1) && (mChannel != -1) && (mComboBlue != -1)) { if (!Microsoft.SPOT.Hardware.SystemInfo.IsEmulator) isvalid = myLego.ComboMode((LegoInfrared.LegoSpeed)mComboBlue,
    (LegoInfrared.LegoSpeed)mComboRed, (LegoInfrared.LegoChannel)mChannel); else Debug.Print("Sent Combo blue " + mComboBlue.ToString()
    + " red " + mComboRed.ToString() + " channel " + mChannel.ToString()); } else isvalid = false; return isvalid; }

    I’ve been thru this kind of explanation couple of times in the previous examples. The code is quite simple, it first call a decrypt function that will return a table containing the parameter name and the value, both as string. More info here. If I take the previous example combo.aspx?bl=8&rd=2&ch=1, it will return 3 params with the pair (bl, 8), (rd, 2), (ch, 1). The idea is to convert and validate those parameters. When one is found, it is converted to the right type and compare to the enums values to check is everything is correct.

    If all parameters are converted correctly and the values are valid, then the ComboMode function is called. If the function is successful, then the value true is return form the function and see the previous section, it will return OK. If not, Problem will be returned.

    As you can see, I check if I’m in the emulator or in a real board. If I’m in the emulator, I will not physically send the signal as it is just an emulator Sourire That allow me to do development in the planes and test the code. Of course, back home, I test them for real, just in case Sourire

    So we now have a way to call our ComboMode function thru a simple URL. I can also create a simple UI to be able to send commands very simply thru a web page. For this, I’ll need to do some HTML. And I have to admit, I don’t really like HTML… The idea of this simple UI is to be able to have dropdown box to select the speed for both the Blue and the Red output but also select the channel. At the end, the UI will looks like this:

    image

    The HTML code to do it is the following for the ComboMode:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head><title></title></head><body>
    <form method="get" action="combo.aspx" target="_blank"><p>Combo Mode<br />
    Speed Red<select id="RedSpeed" name="rd">
    <option label='RED_FLT'>0</option>
    <option label='RED_FWD'>1</option>
    <option label='RED_REV'>2</option>
    <option label='RED_BRK'>3</option>
    </select> Speed Blue<select id="BlueSpeed" name="bl">
    <option label='BLUE_FLT'>0</option>
    <option label='BLUE_FWD'>4</option>
    <option label='BLUE_REV'>8</option>
    <option label='BLUE_BRK'>12</option>
    </select> Channel<select id="Channel" name="ch">
    <option label='CH1'>0</option>
    <option label='CH2'>1</option>
    <option label='CH3'>2</option>
    <option label='CH4'>3</option>
    </select>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input id="Submit1" type="submit" value="Send" /></p></form>
    </body>
    </html>
    

    Nothing rocket science, just a bit of HTML. Please note that the form will be send in get mode so with a URL exactly like the one we want. the target=”_blank” attibute of form is to open it in a new window when the submit button will be clicked. I prefer this as it allow to keep the main windows open and change easily one of the value without changing everything.

    The label attibute of the option tag in a select allow you to put the name you want in the combo list. The value inside the option tag is what will be send. So you can display a friendly name instead of a “stupid” number.

    In terms of code, here is what I have done. This code is part of the ProcessClientGetRequest function:

    // Start HTML document
    string strResp = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional
    //EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
    ; strResp += "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title></title></head><body>"; // first form is for Combo mode strResp += "<form method=\"get\" action=\"combo.aspx\" target=\"_blank\">
    <p>Combo Mode<br />Speed Red<select id=\"RedSpeed\" name=\"rd\">"
    ; strResp += "<option label='RED_FLT'>0</option><option label='RED_FWD'>1</option>
    <option label='RED_REV'>2</option><option label='RED_BRK'>3</option>"
    ; strResp += "</select> Speed Blue<select id=\"BlueSpeed\" name=\"bl\">
    <option label='BLUE_FLT'>0</option><option label='BLUE_FWD'>4</option>
    <option label='BLUE_REV'>8</option><option label='BLUE_BRK'>12</option>"
    ; strResp += "</select> Channel<select id=\"Channel\" name=\"ch\">
    <option label='CH1'>0</option><option label='CH2'>1</option>
    <option label='CH3'>2</option><option label='CH4'>3</option>"
    ; strResp += "</select>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input id=\"Submit1\" type=\"submit\" value=\"Send\" /></p></form>"
    ; strResp = OutPutStream(response, strResp);

    I just create the form as it should be, very simply. Filling a string and outputting the string to the response object. Be careful as in netduino, the maximum size of any object, so including strings is 1024. The strResp object can’t contain more than 1024 caracters, so it is necessary to empty it. The way I do it is thru the OutPutStream function which output the string value into the response stream. I’ve already explained it in a past article.

    So here is it for this part. I’ve explained how to be able to create a set of Web API, very simple to control this infrared emitter. This principle can be apply to anything! I have couple of ideas for the next step. I can implement a system with sensors (can be ILS for examples) and signals (green/red lights) and switch management. But I’m not there yet! Any feedback and ideas welcome.

  • Laurent Ellerbach

    Using netduino and .NET Microframework to pilot any Lego Power Function thru Infrared (part 2)

    • 0 Comments

    In a previous post, I’ve started to describe the Lego Power Function protocol and how I’ve implemented it on a netduino board using .NET Microframework. My work is based on ideas and implementation Mario explain in his blog. We’ve exchange couple of emails to make both our projects work Sourire

    To continue where I stopped, The message_pause function is like this:

     

    private void message_pause(uint channel, uint count)
    {
    
        int a = 0;
        // delay for first message
        // (4 - Ch) * Tm
        if (count == 0)
            a = 4 - (int)channel + 1;
        // next 2 messages
        // 5 * Tm
        else if (count == 1 || count == 2)
            a = 5;
        // last 2 messages
        // (6+2*Ch) * Tm
        else if (count == 3 || count == 4)
            a = 5 + ((int)channel + 1) * 2;
    
        // Tm = 16 ms (in theory 13.7 ms)
        System.Threading.Thread.Sleep(a * 16);
    

    It is a bit more comprehensive if you look at this picture. Each dot represent a signal sent. and each space the time you have to wait.

    image_thumb[10]

    The Lego protocol says you have to wait 16 ms minimum between 2 messages as it is the max size of a message. How did they arrive to this magic number?

    Back to our protocol, we know that the frequency is 38KHz, that the structure of a message starts and stop with a start/stop bit which is composed by 6 pulses IR and 39 pauses. A low bit is a 6 IR pulse and 10 pauses, a high bit a 6 IR pulse and 21 pauses. So we can do a ^simple table like this to have the length in µ seconds and the length in ushort:

    Type Total
    start µs           1 184  
    start ushort                 45  
    stop µs           1 184  
    stop ushort                 45  
    low µs              421  
    low ushort                 16  
    hight µs              711  
    hight ushort                 27  

    And we can also have the view of the full size of a message. The minimum size (if all bits are low) and the maximum one (if all bits are high):

      Total Start Toggle Escape C C a M M M D D D D L L L L stop
    Min size µs 9104 1184 421 421 421 421 421 421 421 421 421 421 421 421 421 421 421 421 1184
    Min size ushort 346 45 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 45
    Max size µs 13744 1184 711 711 711 711 711 711 711 711 711 711 711 711 711 711 711 711 1184
    Max size ushort 522 45 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 45

    So if you do the sum, you can see that the maximum length is 13 744 µ seconds which is 13.744 mili seconds and not 16ms as Lego describe. But lets take the Lego recommendation there. As you can see also the maximum length of a message is 522 ushort. And that’s the perfect transition to have a look at the spi_send function:

    private void spi_send(ushort code)
    {
        try
        {
            ushort[] tosend = new ushort[522]; // 522 is the max size of the message to be send
            ushort x = 0x8000;
            int i = 0;
    
            //Start bit
            i = FillStartStop(tosend, i);
    
            //encoding the 2 codes
            while (x != 0)
            {
                if ((code & x) != 0)
                    i = FillHigh(tosend, i);
                else
                    i = FillLow(tosend, i);
                x >>= 1;  //next bit
            }
            //stop bit
            i = FillStartStop(tosend, i);
            MySerial.Write(tosend);
        }
        catch (Exception e)
        {
            Debug.Print("error spi send: " + e.Message);
        }
    
    }
    
    

    The code starts with the creation of a ushort buffer of 522 elements. It is the max size of a message. The I create a short “x” (ok, I’m not creative for this little increment, but any developer has to use some crappy small names time to time Sourire). I will use it as a mask to see what is the value to send.

    There are now 3 functions called here: FillStartStop, FillHigh and FillLow. They are like this:

    private int FillStartStop(ushort[] uBuff, int iStart)
    {
        //Bit Start/stop = 6 x IR + 39 x ZE
        int inc;
        int i = iStart;
        //startstop bit
        for (inc = 0; inc < 6; inc++)
        {
            uBuff[i] = _high;
            i++;
        }
        for (inc = 0; inc < 39; inc++)
        {
            uBuff[i] = _low;
            i++;
        }
        return i;
    }
    
    private int FillHigh(ushort[] uBuff, int iStart)
    {
        //Bit high = 6 x IR + 21 x ZE
        int inc;
        int i = iStart;
        //High bit
        for (inc = 0; inc < 6; inc++)
        {
            uBuff[i] = _high;
            i++;
        }
        for (inc = 0; inc < 21; inc++)
        {
            uBuff[i] = _low;
            i++;
        }
        return i;
    }
    
    private int FillLow(ushort[] uBuff, int iStart)
    {
        //Bit low = 6 x IR + 10 x ZE
        int inc;
        int i = iStart;
        //Low bit
        for (inc = 0; inc < 6; inc++)
        {
            uBuff[i] = _high;
            i++;
        }
        for (inc = 0; inc < 10; inc++)
        {
            uBuff[i] = _low;
            i++;
        }
        return i;
    }
    

    Those functions take the buffer as an input and where to fill it. And then depending if it is a start/stop, low or high bit will fill the buffer correctly. For example, the low bit is 6 times IR pulses (_high = 0xFE00) and 10 times pauses (_low = 0x0000). And it return the new start position.

    Back to the spi_send function, after calling a first time the FillStartStop, the while loop use the “x” variable as a mask, call FillHigh if it is a high bit and FillLow if it is a low bit. And I change the mask for each bit. High bits have to be send first.

    while (x != 0)
    {
        if ((code & x) != 0)
            i = FillHigh(tosend, i);
        else
            i = FillLow(tosend, i);
        x >>= 1;  //next bit
    }
    

    When all the bits are transformed and the waveform is created, the signal is sent with MySerial.Write(tosend);

    The MySerail object is an SPI object:

    private SPI MySerial;
    

    Initialization is done like this:

    try
    {
        //Frequency is 38KHz in the protocol
        float t_carrier = 1 / 38.0f;
        //Reality is that there is a 2us difference in the output as there is always a 2us bit on on SPI using MOSI
        float t_ushort = t_carrier - 2e-3f;
        //Calulate the outpout frenquency. Here = 16/(1/38 -2^-3) = 658KHz
        uint freq = (uint)(16.0f / t_ushort);
    
        SPI.Configuration Device1 = new SPI.Configuration(
        Pins.GPIO_NONE, // SS-pin
        true,             // SS-pin active state
        0,                 // The setup time for the SS port
        0,                 // The hold time for the SS port
        true,              // The idle state of the clock
        true,             // The sampling clock edge
        freq,              // The SPI clock rate in KHz
        SPI_Devices.SPI1);   // The used SPI bus (refers to a MOSI MISO and SCLK pinset)
    
        MySerial = new SPI(Device1);
    
    }
    catch (Exception e)
    {
        Debug.Print("Error: " + e.Message);
    }
    

    Details on on the math can be found in Mario article. This is a very precise math, the tolerance for the Lego protocol is about 30%. The official document gives the following range value:

    Low bit range 316 - 526 us
    High bit range 526 – 947 us
    Start/stop bit range 947 – 1579 us

    That said, it is better to be in the right domain, make it work better.

    So we’ve seen how to create the waveform, send it over the MOSI output. Now, let see how to use all this in a very simple way.

        public class Program
        {
            public static void Main()
            {
                LegoInfrared myLego = new LegoInfrared();
                for (int i = 0; i < 10; i++)
                {
                    myLego.ComboMode(LegoInfrared.LegoSpeed.BLUE_FWD, LegoInfrared.LegoSpeed.RED_FWD, LegoInfrared.LegoChannel.CH1);
                    System.Threading.Thread.Sleep(1000);
                }
            }
    
        }
        public class LegoInfrared
    

    The LegoInfrared class does contains all the functions and enums I’ve explained. Here the usage is extremely simple. I create an object like this and call 10 times a forward command for both the Blue and Red output on channel 1. I wait 1 second and do it again. And the good news is that it is really working. I’m of course using the electronic schema that Mario proposed.

    If you are interested in the full source code of the full protocol, just let me a comment.

    More to come to show how to pilot it thru a web server and how to use it from another program. And again, depending of my inspiration, we will go a bit further and use sensors to raise events and be a bit smarter. Stay tune Sourire. If you want to implement other protocols like RC5, you can directly go to Mario blog and use his code. If you have a more complex protocol like the Lego one, you’ll be able to reuse most of the implementation I’ve done. Let me know if you want the full code.

  • Laurent Ellerbach

    Using netduino and .NET Microframework to pilot any Lego Power Function thru Infrared (part 1)

    • 2 Comments

    I’m part of FREELUG, the French Enthusiast Lego User Group. And in this group, there are lots of discussions on Lego of course. In one of the thread someone ask the question if it was possible to pilot an Lego train using the new Power Function with a PC. The need is during expo, it makes it easier to run trains, stop them in a programmatic way.

    image

    I did a quick answer on the list saying that it can be quite easy if the protocol was not too complex and the IR technology used was close to RC5 from Philips. A small oscillator behind a serial or parallel port would do the trick. Philo, one of the FREELUG member answer me with a link to the protocol. And also tell me it should not be as easy as I was thinking. And he was more than right! No real way to make this work with a simple serial or parallel port on a PC. The protocol is more complex and need quite a bit of work to implement. I’ll come later on the first explanation on how to do it.

    So I decided to see if it was possible to implement this on netduino using .NET Microframework. this board has lots of IO, analogic and digital, do implement busses like I2C but also SPI. As any project, I started my project with my friend Bing. And start searching for similar projects. And I found Mario Vernari who I’ve mentioned in my previous post who was doing something similar. And we’ve exchange couple of emails to find a good way to implement an Infrared emitter using .NET Microframework. We will create the wave form in a buffer and then send it thru the MOSI port of an SPI port linked to the infrared led. So I will use the ideas and implementation Mario explain in his blog to pilot the Lego Power Function.

    I let go thru Mario article to get the basics of the IR protocol in general. And I will focus here on the specific Lego implementation and of course the specific code to make it work.

    Reading the 14 pages of the Lego protocol, we learn that the IR signals are using 38 kHz cycles. An IR Mark is 6 on and off signals as shown in the next picture

    image

    Each message will start and stop with a Start/Stop bit. This bit is 6 IR Mark and 39 pauses. So if I represent it in a binary way it will be:

    101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000

    As Mario described in his post, we will use ushort to create the wave length. So in this case it will looks like

    0xFF00 0xFF00 0xFF00 0XFF00 0xFF00 0xFF00 and 39 times 0x0000

    Reality is a bit different as when using MOSI on a SPI to output a signal it is always a 1 for couple of µ seconds. So the right value to use is 0xFE00

    The low bit is working the same way, it is 6 IR Mark and 10 cycles of pause, the high one 6 IR Mark and 21 cycles of pause.

    So if I want to send the binary value 10011 I will send 6 IR Marks, 21 pauses, 6 IR Marks, 10 pauses, 6 IR Marks, 10 pauses, 6 IR Marks, 21 pauses, 6 IR Marks, 21 pauses. And I will create a ushort buffer which will contains 6 times 0xFE00, 21 times 0x0000, 6 times 0xFE00, 10 times 0x0000, 6 times 0xFE00, 10 times 0x0000, 6 times 0xFE00, 21 times 0x0000, 6 times 0xFE00, 21 times 0x0000

    All this make the Lego protocol complex compare to the RC5 and other similar protocols where the Low bit and high bits are usually the same size, the IR Mark is just inverted and the pause same size as the IR Mark.

    Now let have a look at the protocol itself.

    image

    The protocol start and stop with our Start/Stop bit describe up in the article. And then have 4 nibble. One nibble is a 4 bit data. The last nibble is used to to a check sum and is called LRC LLLL = 0xF xor Nibble 1 xor Nibble 2 xor Nibble 3.

    There are 4 channels possible going from 1 to 4 represented as CC from 0 to 3.

    a is not used in this protocol for the moment and kept for a future implementation. So it has to be set to 0.

    E is 0 for most modes except one specific mode (PWM)

    Toggle is an interesting one. The value has to change each time a new command is sent. So if the first time you send a command on a specific Channel (let say 1), it is 0, the next command send on Channel 1 will have to set Toggle as 1.

    The Power Function have different modes available (MMM):

    000 Not used in PF RC Receiver
    001 Combo direct (timeout)
    010 Single pin continuous (no timeout)
    011 Single pin timeout
    1xx Single output

    To know which mode is doing what, just refer to the protocol. I will detail the Combo direct (timeout) mode as an example for the rest of the article. It is easy to understand how it is working. The others are not much more complex and the logic is the same.

    image

    Mode (MMM) here is 001. Channel (CC) will vary form 0 to 3 depending which channel you want to pilot. So here, the Data nibble is split into 2 parts BB and AA. The documentation give this:

    B output BB,, called Red in all receivers

    00xx Float output B
    01xx Forward on output B
    10xx Backward on output B
    11xx Brake output B

    A output AA, called Blue in all receivers

    xx00 Float output A
    xx01 Forward on output A
    xx10 Backward on output A
    xx11 Brake output A

    And an interesting information is that Toggle bit is not verified on receiver. So if you don’t want to implement it, it’s possible.

    So it’s time to write some code Sourire Let start with couple of enums to facilitate the usage:

    //mode public enum LegoMode {
        COMBO_DIRECT_MODE = 0x1,
        SINGLE_PIN_CONTINUOUS = 0x2,
        SINGLE_PIN_TIMEOUT = 0x3,
        SINGLE_OUTPUT = 0x4
    };
    
    //speed public enum LegoSpeed {
        RED_FLT = 0x0,
        RED_FWD = 0x1,
        RED_REV = 0x2,
        RED_BRK = 0x3,
        BLUE_FLT = 0x0,
        BLUE_FWD = 0x4,
        BLUE_REV = 0x8,
        BLUE_BRK = 0xC
    };
    
    //channel public enum LegoChannel {
        CH1 = 0x0,
        CH2 = 0x1,
        CH3 = 0x2,
        CH4 = 0x3
    };
    

    The LegoMode one will be used to setup the mode (MMM), the LegoSpeed for the AA and BB output and the LegoChannel to select the Channel.

    private uint[] toggle = new uint[] { 0, 0, 0, 0 };
    
    public void ComboMode(LegoSpeed blue_speed, LegoSpeed red_speed, LegoChannel channel)
    {
        uint nib1, nib2, nib3, nib4;
    
        //set nibs nib1 = toggle[(uint)channel] | (uint)channel;
        //nib1 = (uint)channel; nib2 = (uint)LegoMode.COMBO_DIRECT_MODE;
        nib3 = (uint)blue_speed | (uint)red_speed;
        nib4 = 0xf ^ nib1 ^ nib2 ^ nib3;
    
        sendMessage((ushort)nib1, (ushort)nib2, (ushort)nib3, (ushort)nib4, (uint)channel);
    }
    

    I have defined a toggle table which will contain the value of the toggling. The function ComboModo takes as argument, the channel and the AA and BB parameters.

    The code is quite straight forward, I build the 4 nibbles like in the description.

    nib1 contains the Toggle plus escape (0) plus the channel. Toggle is not mandatory in this one but I’ve implemented to show you how to do it. and the values the Toggle will take will be in binary 1000 or 0000 so 8 or 0 in decimal.

    nb2 is E (which is 0) and the Mode (MMM) which is 1 in our case.

    nib3 combine AA and BB to select the Blue and Red orders.

    nib4 is the check sum.

    And then I call a function called sendMessage. I’ve build all the modes the same way, implementing simply the protocol.

    Now, let have a look at the sendMessage function:

    private void sendMessage(ushort nib1, ushort nib2, ushort nib3, ushort nib4, uint channel)
    {
        ushort code = (ushort)((nib1 << 12) | (nib2 << 8) | (nib3 << 4) | nib4);
        for (uint i = 0; i < 6; i++)
        {
            message_pause(channel, i);
    
            spi_send(code);
        }
        if (toggle[(int)channel] == 0)
            toggle[(int)channel] = 8;
        else toggle[(int)channel] = 0;
    
    }
    

    4 nibbles of 4 bits is 16 bits so a ushort. And I’m building this ushort simply with all the nibbles. OK, the protocol is a bit more complex than only sending 1 time a command. Each command has to be sent 5 times. What make the protocol not easy is that you have to wait different amount of time depending on the channel and the number of time you’ve already send a command! That is the job of the message_pause function. The spi_send send the code Sourire. The rest is about toggling the toggle bit of the channel.

    That’s it for today. In the next blog post, I’ll continue to go more in the details, show the implementation of the missing functions. And when I’ll finish to explain all the protocol code, I’ll go a bit further with a way to remotely using a web page or equivalent send commands to the netduino board which will send the IR command. And if I have more time, I will also implement sensors to detect if a train or a vehicle is on a specific place. This will be extremely easy as I’ve already explain how to use sensors like this.

  • Laurent Ellerbach

    Using 2 identical I2C device on the same I2C bus (solution working better)

    • 0 Comments

    In one of my past posts, I’ve try to use 2 identical I2C devices on the same bus. Mario Vernari who help me for another problem on my Lego city and with whom I’ve exchange a bit to find other solutions help me there two. Mario is coming from the electronic side and I come from the software side.  So he can correct me when I’m wrong with my electronic Sourire. And I was quite wrong with the previous solution trying to switch on and off the power of the sensors. Mario gave me couple of good reasons:

    “First off, any silicon embeds diodes, thus -even unpowering a device- there's a non-zero current flowing into. In this case, through the SCL/SDA lines, via pull-ups.

    Secondly, you're using sensors, and they typically need a certain time to settle their internal state, reach the steadiness, etc. There are also "smarter" sensors, which perform a kind of auto-calibration when they are powered up. If you switch off, you'll lose those benefits.”

    And he gave me a tip: “use a 74HC4052”. So lets go and see what it is. It’s a switch for analog signals. You have 4 inputs (named Ya, a = 0 to 3) and 1 output (named Z). But they are 2 ways. So when you have selected one line, you can send signals in both ways. And there are 2 of those in the chip (naming will be nY and nZ, n = 1 and 2).

    That allow to switch the overall SDA and SCL bus to the right sensor. And this will allow to pilot up to 4 identical sensors. The selection of the line is made by the S0 and S1 with the following rule:

    Input     Channel on
    E S1 S0  
    L L L nY0 and nZ
    L L H nY1 and nZ
    L H L nY2 and nZ
    L H H nY3 and nZ
    H X X none

    So regarding the code I wrote for the previous post, it will remain the same! It will work exactly the same way. What is changing is the electronic part. And here is the new design:

    image

    Mario also give me the following advice: “Note that when you cut off a device, you should provide the pullups anyway”. So That’s what I did by putting the pullups for each component.

    Now it’s working and much better as the line switch is really fast and there is no need to wait for a long time to read the data. So thanks Mario for the tip!

  • Laurent Ellerbach

    Create your own mobile video recorder or animation stand

    • 1 Comments

    Long time ago, when I was doing lots of demos and used to have to display mobile phone like smartphone of Windows Embedded devices, I needed a mobile video recorder to be able to display them. Of course, I though using a webcam but the webcam alone does not allow you to demo the device. And I figure out that those kind of animation stand costs lots of money and were not easy to transport and very costly to rent. So I decided to build my own. And I recently use it again as I had to demo my Windows Phone 7 device and also .NET Microframework device like netduino.

    The main features I needed were:

    • easy to transport
    • very cheap
    • using my PC if needed like using a webcam

    So I came to the following solution:

    WP_000047

    Everything can be unplugged and transported easily. It is using a webcam and simple plastic pipes. It costs only couple of euros ($ for our non European friends Sourire) to build. On the software side, I used a DirectX sample which I customize to create my own application.

    And I sued this solution very recently during the French TechDays where I did a demo of .NET Microframework. The equipment in place was not working and I was glad to have my own mobile video recorder with me Sourire So, I use it as you’ll be able to see when the video will be available.

    so let start with the hardware part. what you’ll need:

    image

    Now to build it, you’ll need to cut the following parts:

    • Cut a length of 160 mm in the Ø 20 pipe
    • Cut a length of 60 mm in the Ø 20 pipe
    • Cut a length of 200 mm in the Ø 20 pipe
    • Cut a length of 150 mm in the Ø 20 pipe
    • Cut a length of 200 mm in the Ø 14 pipe
    • Cut a length of 130 mm in the Ø 14 pipe

    And here is the technical schema (forget about the webcam yet):

    image

    With this you can basically adapt any camera. You may recognize on this picture an old Philips webcam and on the one I pick recently a nice Microsoft LifeCam Cinema. A perfect HD camera with some good feature to tune the brightness. Also, it is very easy to install the camera on the pipes.

    Step 1: glue assembly

    • Glue the 160 mm Ø 20 pipe and glue the 60 mm Ø 20 pipe with the T
    • Glue the bend Ø 20 pipe at the end of the 30 mm Ø 20 pipe
    • Be sure the T top is vertical
    • Be sure the bend is horizontal

     image

    Step 2: soft assemblies

    • Place scotch in the length around the 200 mm Ø 14 pipe on 150 mm. Place scotch until the 200 mm Ø 14 pipe go well and block when placed in the 150 mm Ø 20 pipe. This will allow to move up and down the webcam.
    • You can glue or use scotch to place the bend Ø 14 and the end of the 200 mm Ø 14 pipe. Glue or scotch it at the other end you place the scotch from the previous step

    image

    • To finalize this part, place the stop diameter Ø 14 pipe on the 200 mm Ø 14 pipe and place this pipe in the 150 mm Ø 20 pipe

    On the software side, I’m using a simplified version of the DirectX SDK AMCAP example. You can easily select the webcam you want (if you have an integrated webcam and the external one, make it easy to choose) and setup the settings in the capture filter like the autofocus, the resolution, etc.

    image

    If you want this software let me know and write me at laurelle@microsoft.com.

    I hope you’ve enjoy this tutorial to create hardware which is not electronic this time Sourire

  • Laurent Ellerbach

    Using 2 identical I2C device on the same I2C bus

    • 0 Comments

    If you know a bit about I2C bus, it is impossible to use 2 identical devices with the same address on the bus. Read my previous article to understand more on how it’s working. But as always, you can find trick to make it works.

    In my case, I’m using a TC74 I2C temperature sensor from Microchip. Their bus address is the same (0x4D). Plugging 2 on the same bus will create a redundancy but that’s all what you’ll get. If you want to place them in 2 different locations, you’ll never be sure which one will give you the right temperature.

    I get the idea of powering on one sensor and powering the other one off to make sure only one of the device will be on and will respond to the requests. To do that I’m using one digital IO. In the state high (1), one of the sensor will be on and on state low (0) the other will be on.

    So I’ve decided to do the following hardware implementation:

    image

    and how it looks like for real Sourire

    WP_000164

    When D0 will be high (1), the TC74 #1 will be alimented and when it will be low (0), the TC74 #2 will be alimented. Both transistors are playing the role of switch there. Each TC74 need approximately 300 ms to get fully initialized. So in the code, before accessing any of the sensor, right after switching, we will have to wait a bit. But overall, this simple and smart solution will work with more than 2 sensors, if you need a third or a fourth one, just add another IO and do a bit of logic. And that’s it!

    The .NET Microframework (NETMF) code is very simple, based on the same example as the previous post, it will looks like this:

    public static void Main()
    {
        TC74Device MyTC74 = new TC74Device(0x4D); //0x4D
        OutputPort MySelect = new OutputPort(Pins.GPIO_PIN_D0, false);
        Thread.Sleep(1000);
        byte MyData;
        sbyte MyTemp;
        MyTC74.Init();
        MySelect.Write(!MySelect.Read());
        Thread.Sleep(1000);
        MyTC74.Init();
        while (MyTC74.IsReady())
        {
            MyTemp = MyTC74.ReadTemperature();
            Debug.Print("Temperature :" + MyTemp);
            MyData = MyTC74.ReadRegister();
            Debug.Print("Register :" + MyData);
            Thread.Sleep(1000);
            MySelect.Write(!MySelect.Read());
            Thread.Sleep(1000);
            //MyTC74.Standby(true);
        }
    }

    So nothing really different from the previous post except that a digital IO is created and the state is changed every time in the infinite loop. And there are a 1s sleep before access any of the sensor. As for the netduino, the component is the same, it is declared one time. But in terms of programming, we know we have 2 different sensors Sourire Up to you to create a class to select which sensor you want to measure and play with the sleep if needed.

    I did put the sensors outside (I’m on vacations in the mountains) and run the program. I put my fingers on one of the sensor so the temperature get higher. And the result is the following:

    Temperature :-4
    Register :64
    Temperature :21
    Register :64
    Temperature :-4
    Register :64
    Temperature :23
    Register :64
    Temperature :-4
    Register :64
    Temperature :24
    Register :64
    Temperature :-4
    Register :64
    Temperature :23
    Register :64
    Temperature :-4
    Register :64
    Temperature :21
    Register :64

    So as you can see, the outside temperature is –4 and my fingers warmed up the sensor to 21-23 degrees. It was cold so I did not wait the full time to get to the 37 degrees or so it should be Sourire

    I hope you’ll enjoy the trick Sourire Feedback from electronic guys welcome.

  • Laurent Ellerbach

    Using one temperature sensor with I2C protocol and .NET Micro framework on netduino board

    • 2 Comments

    I wanted to play with a temperature sensor. And when the time came to choose one, I was amaze to see how many of those sensor exists. Some were simple resistor like the light sensor I used in one of my previous example, some were more like transistors, and couple integrated more advanced features. And I choose a TC74 from Microchip as it includes an I2C communication protocol and was extremely cheap (less than 1€ for the cheap). And they were sold by 2 so I get 2 of them Sourire My main idea was to be able to get the temperature of both of them.

    So I started to understand how I2C was working. The basic idea is simple: you have a clock going from the master (the netduino board in my case) to slaves (the TC74) and a line with data which is bidirectional. So the master can speak to the slave and the slave to the master.

    Good explanation on how this bus works in details in Wikipedia for example. The main difficulty with this protocol is to understand that you are sending information and can continue to send or receive some depending on what you’ve asked. But I’ll explain this later. Every device has an address on the bus and will respond when this address is send on the bus. That’s the ACK below.

    This table is coming from the TC74 documentation and explain how to write, read and receive a byte from the TC74.

    image

    There are simple commands and more complex one. The more complex one are usually accessing registers to setup and tweak a bit the device. In the case of the TC74, the register can be read and write. But it’s extremely simple as there are only 2 registers. One to see if a temperature is ready to read and one to put the device in standby mode or read if it is standby.

    image

    And the associated value to the register is simple also. D[7] is the high bit and D[0] the lowest one.

    image

    Then the read function return the temperature in a sbyte according the to table bellow:

    image

    Last but not least, here is how to connect the pins:

    image

    You don’t have to forget to put a resistor between the SDA and SCL lines like in the schema here. I used 10KΩ resistors and it’s working perfectly. I need to run more tests to see how long the cables cans be. I guess that if I need long cables, I’ll need to lower the value of this resistor.

    That’s it for the hardware part. Now, on the soft part, I started to search using bing and found couple of good articles to explain how to use I2C. This first one gives you an overall example and this second one a class to be used with multiples slaves. What I liked with the second one is that it’s easy to use it with multiples slaves. And in the future, I may want to add other sensors like a barometer and humidity sensor using I2C. Or even create my own I2C sensor as there are existing chip to be the interface.

    On top of this code, I’ve implemented a class called TC74 which implement all features of this sensor and calling the I2C class. So the overall code is quite simple.

    namespace TC74
    {
        //Command Code Function
        //RTR 00h Read Temperature (TEMP)
        //RWCR 01h Read/Write Configuration
        //(CONFIG)
        public enum TC74Command: byte
        {
            ReadTemperature = 0x00,
            ReadWriteRegister = 0x01
        };
        
        public enum TC74Config: byte
        {
            READY = 0x40,
            STANDBY = 0x80
        };
        /// <summary>
        /// This is an I2C temperature sensor.
        /// </summary>
        public class TC74Device
        {
            private I2CDevice.Configuration _slaveConfig;
            private const int TransactionTimeout = 3000; // ms
            private const byte ClockRateKHz = 100;
            public byte Address { get; private set; }
    
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="address">I2C device address 
    of the TC74 temperature sensor
    </param> public TC74Device(byte address) { Address = address; _slaveConfig = new I2CDevice.Configuration(address,
    ClockRateKHz); } public sbyte ReadTemperature() { // write register address I2CBus.GetInstance().Write(_slaveConfig, new byte[]
    { (byte)TC74Command.ReadTemperature }, TransactionTimeout); // get the byte result byte[] data = new byte[1]; I2CBus.GetInstance().Read(_slaveConfig, data,
    TransactionTimeout); //force the convertion to a signed byte return (sbyte)data[0]; } public byte ReadRegister() { // get the Register byte[] data = new byte[1]; I2CBus.GetInstance().ReadRegister(_slaveConfig,
    (byte)TC74Command.ReadWriteRegister, data, TransactionTimeout); return data[0]; } public void Init() { byte[] data = new byte[2] { (byte)TC74Command.ReadWriteRegister, 0x00 }; I2CBus.GetInstance().Write(_slaveConfig, data, TransactionTimeout); I2CBus.GetInstance().Write(_slaveConfig, new byte[]
    { (byte)TC74Command.ReadTemperature }, TransactionTimeout); } public bool IsReady() { bool bready = false; byte ret = ReadRegister(); if ((ret | (byte)TC74Config.READY) == (byte)TC74Config.READY) bready = true; return bready; } public void Standby(bool stdby) { byte[] data = new byte[2] { (byte)TC74Command.ReadWriteRegister, 0x00 }; if (stdby) data[1] = (byte)TC74Config.STANDBY; I2CBus.GetInstance().Write(_slaveConfig, data, TransactionTimeout); } } }

    Starting with the constructor, the address need to be stored. This address is b1001101 (0x4D) as I have a TC74A5-5.0VCT. We will use it later in a sample code. And this device works very well at 100KHz.

    Then the function Init is there to initialize the device. First it write in the internal register the value 0 to make sure it is not in standby mode. And then it write ReadTemperature to make sure we’ll be able to read the temperature.

    The register function read the register and return the byte value.

    The IsReady function read the register to check if the device is ready. It is only ready when power is up for enough time and before shut down. It is also not ready when the device is on standby mode.

    Standby set or unset the standby mode. It write in the register the STANDBY value which is 0x80 (b10000000).

    So pretty straight forward code and simple as well.

    public static void Main()
    {
        TC74Device MyTC74 = new TC74Device(0x4D); //0x4D
        byte MyData;
        sbyte MyTemp;
        Thread.Sleep(1000); 
    MyTC74.Init(); while (MyTC74.IsReady()) { MyTemp = MyTC74.ReadTemperature(); Debug.Print("Temperature :" + MyTemp); MyData = MyTC74.ReadRegister(); Debug.Print("Register :" + MyData); Thread.Sleep(1000); //MyTC74.Standby(true); } }

    The basic example to use this sensor is also quite easy. The device is initialized with the 0x4D address. Then the device is initialized. And the temperature and register are ready every second, if you want to test the Standby function, just unhide the last line, it will put the device in the standby mode and the device won’t be ready so the code will return.

    If you’ve done something wrong, exception will be raised and your code will stop.

    Now that’s how to pilot one sensor. The question is what can be done to read 2 identical sensors with the same address? I did it Sourire and it will be the topic of the next post. Stay tune!

  • Laurent Ellerbach

    Some hard to pilot a Sprinkler with .NET Microframework

    • 0 Comments

    In previous post, I’ve explained I want to pilot my sprinklers with a netduino board. I’ve already write couple of articles around it, including how to create a HTTP web server, set up the date and time, manage parameters, launch timers, securing the access, pilot basic IO. I’ve also shown couple of examples including this Sprinkler solution during the French TechDays. The video is available. I just love .NET Microframework (NETMF) Sourire so good to have no OS such as Linux or Windows, just a managed .NET environment!

    During the TechDays, I get questions on the electronic part of this demo. So in this post, I’ll explain how I did it and show code example to make it happen. Back to my Sprinklers, the brand is Gardena. The electro valves I have to pilot are bi valves. They need a positive 9V pulse to open and a 9V negative one to close. Gardena do not publish any information regarding there valves but that is what I found with couple of tests.

    The netduino board have a 3.3V and a 5V alimentation and the intensity is limited if alimented with the USB port. So not really usable to generate a 9V pulse. Plus I don’t want to mix the netduino electric part and the valve one. So I will use simple photosensitive octocouplers. The way it’s working is simple, you have a led and a photosensitive transistor, when lighted, the transistor open. The great advantage is you have a very fast switching totally isolated circuit.

    I pick a cheap circuit with 4 octocouplers (ACPL-847-000E) as I will need 4 per valves.

    image

    The basic idea is to be able to be able to send some current in one way to open the valve and in the other to close it. And to pilot it, I will use the digital IO from the netduino. I will need 2 IO per vavle. One to pilot the “Open” and one to pilot the “Close”. I just can’t use only one IO as I will need to send short pulses to open and short pulses to close. I want to make sure I’ll close the valve as well as opening it. and not only one single pulse. One IO won’t be enough as I need to have 3 states: open, close and “do nothing”.

    When I will have the first IO open (let call it D0) at 1, I will open the valve. When the second one (D1) will be set at 1, I will close the valve. And of course when both will be at 0, nothing will happen as well as when both will be at 1. So I will need a bit of logic with the following table:

    D0 D1 Pin On Pin Off
    0 0 0 0
    0 1 0 1
    1 0 1 0
    1 1 0 0

    So with a bit of logic, you get quickly that Pin On = D0 && !D1 and Pin Off = !D0 && D1 (I’m using a programming convention here). So I will need couple of inverters and AND logical gates. I’ve also choose simple and cheap ones (MC14572UB and CD74HC08EE4). They costs couple of euro cents. Those components have all what I need.

    image

    For the purpose of this demo, I will use 2 inverted led (one green and one red) and will not send pulse but a permanent current. So it will be more demonstrative in this cold winter where I just can’t test all this for real with the sprinklers! I’ll need a new post during spring Sourire

    Now, when I put everything, here is the logical schema:

    image

    I will have to do this for each of my sprinklers. I have 3 sprinklers in total. And here is a picture of a real realization:

    WP_000160

    You can also see a push button in this picture (on the left with white and blue wires). I’m using it to do a manual open and close of the sprinklers. I’m using here the IO D10. When I’ll push the switch, it will close the valve if it is open and open it if it is closed.

    I’m done with the hardware part! Let see the code to pilot all this. The overall code for the Sprinkler class looks like this:

    public class Sprinkler {
        private bool MySpringlerisOpen = false;
        private int MySprinklerNumber;
        private bool MyManual = false;
        private OutputPort MySprOpen;
        private OutputPort MySprClose;
        private Timer MyTimerCallBack;
        private InterruptPort MyInterPort;
        private long MyTicksWait;
    
        public Sprinkler(int SprNum)
        {
            MySprinklerNumber = SprNum;
            MyTicksWait = DateTime.Now.Ticks;
            switch (SprNum)
            {
                case 0:
                    MySprOpen = new OutputPort(Pins.GPIO_PIN_D0, false);
                    MySprClose = new OutputPort(Pins.GPIO_PIN_D1, true);
                    MyInterPort = new InterruptPort(Pins.GPIO_PIN_D10,
    false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh); break; case 1: MySprOpen = new OutputPort(Pins.GPIO_PIN_D2, false); MySprClose = new OutputPort(Pins.GPIO_PIN_D3, true); MyInterPort = new InterruptPort(Pins.GPIO_PIN_D11,
    false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh); break; case 2: MySprOpen = new OutputPort(Pins.GPIO_PIN_D4, false); MySprClose = new OutputPort(Pins.GPIO_PIN_D5, true); MyInterPort = new InterruptPort(Pins.GPIO_PIN_D12,
    false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh); break; } if (MyInterPort != null) MyInterPort.OnInterrupt += new NativeEventHandler(IntButton_OnInterrupt); } // manual opening based on an interupt port // this function is called when a button is pressed static void IntButton_OnInterrupt(uint port, uint state, DateTime time) { int a = -1; switch (port) { case (uint)Pins.GPIO_PIN_D10: a = 0; break; case (uint)Pins.GPIO_PIN_D11: a = 1; break; case (uint)Pins.GPIO_PIN_D12: a = 2; break; } if (a >= 0) { //wait at least 2s before doing anything if ((time.Ticks - MyHttpServer.Springlers[a].MyTicksWait) > 20000000) { if (!MyHttpServer.Springlers[a].MySpringlerisOpen) { MyHttpServer.Springlers[a].Manual = true; MyHttpServer.Springlers[a].Open = true; } else { MyHttpServer.Springlers[a].Open = false; } MyHttpServer.Springlers[a].MyTicksWait = DateTime.Now.Ticks; } } } // open or close a sprinkler public bool Open { get { return MySpringlerisOpen; } set { MySpringlerisOpen = value; //do harware here if (MySpringlerisOpen) { MySprOpen.Write(true); MySprClose.Write(false); } else { MySprOpen.Write(false); MySprClose.Write(true); MyManual = false; } } } public bool Manual { get { return MyManual; } set { MyManual = value; } } //read only property public int SprinklerNumber { get { return MySprinklerNumber; } } public Timer TimerCallBack { get { return MyTimerCallBack; } set { MyTimerCallBack = value; } } }

    Have a look at the previous posts to understand how to use it thru a web server. This part, is only the class to pilot the sprinklers. I know I only have 3 sprinklers so there are many things hardcoded. It’s embedded and no one else will use this code. It’s more efficient like this. The size of the program has to be less than 64K (yes K and not M or G!). The netduino board has only 64K available to store the program.

    The initialization of the class will create 2 OutputPort per valve. As explain in the hardware part, one to open and one to close the valve. It will also create one InterruptPort to be able to manually open and close the valve. In order to understand how those ports are working, please refer to this post.The initialization will setup to port with default values. False for the pin D0 which pilot the “open” valve and True for the pin D1 which pilot the “close” valve.

    The IntButton_OnInterrupt function will be called when a switch will be pressed. Depending on the pin, it will close or open the valve linked to the specific pin.

    The Open property will open or close the valve. In my project, I’ll use pulse to open the valve, for this demo, I’m using continued output so the led will be either red (close) or green (open). The 2 leds are mounted in an opposite way so when the current is in one way it will be red and in the other it will be green.

    The TimerCallBack function is used when a Sprinkler need to be switch off. The associated code is:

    static void ClockTimer_Tick(object sender)
    {
        DateTime now = DateTime.Now;
        Debug.Print(now.ToString("MM/dd/yyyy hh:mm:ss"));
        //do we have a Sprinkler to open? long initialtick = now.Ticks;
        long actualtick;
        for (int i = 0; i < SprinklerPrograms.Count; i++)
        { 
            SprinklerProgram MySpr = (SprinklerProgram)SprinklerPrograms[i];
            actualtick = MySpr.DateTimeStart.Ticks;
            if (initialtick>=actualtick)
            { // this is the time to open a sprinkler Debug.Print("Sprinkling " + i + " date time " + now.ToString("MM/dd/yyyy hh:mm:ss"));
                Springlers[MySpr.SprinklerNumber].Manual = false;
                Springlers[MySpr.SprinklerNumber].Open = true;
                // it will close all sprinkler in the desired time of sprinkling. Timer will be called only once. //10000 ticks in 1 milisecond Springlers[MySpr.SprinklerNumber].TimerCallBack = 
    new Timer(new TimerCallback(ClockStopSprinkler), null, (int)MySpr.Duration.Ticks/10000, 0); SprinklerPrograms.RemoveAt(i); } }

    The ClockTimer_Tick fonction is called every 60 seconds. It check if a sprinkler need to be switch one. If yes, a timer is created and associated with the TimerCallBack timer. And this timer will be called after the amount of time programmed to be open.

    static void ClockStopSprinkler(object sender)
    {
        Debug.Print("Stop sprinkling " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"));
        //close all sprinklers if automatic mode for (int i = 0; i < NUMBER_SPRINKLERS; i++)
        {
            if (Springlers[i].Manual == false)
            {
                Springlers[i].Open = false;
                Springlers[i].TimerCallBack.Dispose();
            }
        }
    }

    The function is quite simple, it just call the Open property to close all the spinklers. I’ve decided to do this as in any case, I don’t have enough pressure to have all them open. Of course, to be complete, all timers will be close. The Manual check will not close the sprinkler.

    So that’s it for this post. I hope you’ll enjoy it! And this time, I’m not in a plane to write this post, I’m on vacation Sourire

  • Laurent Ellerbach

    Using basic IO with .NET Microframework

    • 0 Comments

    Here is the code from my first French TechDays demo. The video is available here. During this first demo, I explained how to use the IO in a simple way: OutputPort, InterruptPort, InputPort and Analogic input ports. So those ports are really the basic one you can use in a .NET Microframework (NETMF) boards like the netduino one I’m using. All boards do also includes more advances IO like UART (serial), SPI, I2C and more. I’ll probably do other posts to explain how to use more advance ports.

    Here is the structure of the code and the global variables. I’ll use this to explain each function later in this 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.NetduinoPlus;
    
    namespace ButtonBlinking
    {
        public class Program {
            static OutputPort LED;
            static InterruptPort IntButton;
            static InputPort Button;
            static bool IsBlinking = false;
    
            public static void Main()
            public static void Blinking()
            public static void LightWhenOpturated()
            static void IntButton_OnInterrupt(uint port, uint state, DateTime time)
            public static void Blink()
            public static void ButtonPressedLight()
            public static void ReadAnalogic()
        }
    }

    As their name are very explicit, an OutputPort is a digital IO port to do an outpout. Main functions are Write and Read. And you write or read a boolean. Write(true) will outpout a high signal (1) and write(false) will output a low signal (0).

    An InputPort is also very explicit Sourire. You can read it. It can be high (true, 1) or low (false, 0).

    An InterruptPort is an input port but it can raise interruption when there is a change in the status of the the port.

    Now you get the bases, lets go for more. To execute this code, you’ll need couple of hardware things:

    • leds (1 or 2 is quite enough)
    • resistors (65 ohms)
    • a press button or a switch
    • a light sensor resistor or temperature sensor resistor

    For the main function, the code is simple, it just call the various sub function we will review in detail. So unhide the function you want to execute:

    public static void Main()
    {
        //Demo 1: blinking a led //Blinking(); //Demo 2: lighting a led when button pressed //ButtonPressedLight(); //Demo 3: blinking a led when a sensor is opturated //LightWhenOpturated(); //Demo 4: Analogic input //ReadAnalogic(); Thread.Sleep(Timeout.Infinite);
    }

    So we will start with the most basic demo you can do with IO on a NETMF board like netduino: blinking a led. This this the hello world of hardware Sourire

    The code is very simple:

    public static void Blinking()
    {
        //Open an OutputPort LED = new OutputPort(Pins.GPIO_PIN_D0, true);
        while (true)
        {
            //write the opposite value read in the LED status LED.Write(!LED.Read());
            //wait some time Thread.Sleep(200);
            //effect = blinking }
    }

    You create an OutputPort one of of the digitial IO. Here the 0. And in an infinite loop, you write the opposite of the value you read on this port. And wait couple of milliseconds before doing this operation.

    image

    On the hardware part, all what you have to know is a simple rule: U = RxI

    The output port is a 3.3V on a netduino. And reading the documentation of a led, the average voltage is 2V (vary a bit from green, red and orange) and the current it normally need to receive is 0.02A.

    So applying this to calculate the needed resistor will give R = (3,3 – 2)/0,02 = 65 Ohms

     

     

    Plug the resistor on pin D0 of the board, and then the led and connect it to the ground.

    image

    Run the code. And the magic happen Sourire you have a lighting led. Wow!!!! Congratulations, you’ve achieve level 1: blinking the led. Good! Want more? OK, you’ll get more.

    Now let control the led regarding the state of a press button (or interrupter/switch).

    The code is also very simple and straight forward:

    public static void ButtonPressedLight()
    {
        LED = new OutputPort(Pins.GPIO_PIN_D0, true);
        Button = new InputPort(Pins.GPIO_PIN_D5, false, Port.ResistorMode.PullUp);
        while (true)
        {
            LED.Write(Button.Read());
            Thread.Sleep(10);
        }
    
    }

    We are creating an outpout port, an input port and in an infinite loop, we aligned the state of the button with the state of the switch. On the electronic part, also very simple:

    image

    So when you will close the switch, the state of the input port will go to the ground so to 0 and it will switch off the Led. When the switch will be open, the state is high so 1 and the led will be lighted.

    The next one is about the same. The idea is to blink the led 5 times when the switch is closed and 5 times when it is open again. As you can imagine, it’s not easy to do in an in finite loop like previously. Plus, you will probably use your board to do something while you are waiting for the user to do an action or to get a state change on a pin. For this, there is then interrupt port. The idea is to raise an event when the state change. And as you will do with a regular .NET code, you’ll handle it and do something in this event handler.

    Here is the code:

    public static void LightWhenOpturated()
    {
        LED = new OutputPort(Pins.GPIO_PIN_D0, false);
        // the pin will generate interrupt on high and low edges IntButton = new InterruptPort(Pins.GPIO_PIN_D12, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
        // add an interrupt handler to the pin IntButton.OnInterrupt += new NativeEventHandler(IntButton_OnInterrupt);
    }
    
    static void IntButton_OnInterrupt(uint port, uint state, DateTime time)
    {
        if (IsBlinking == false)
            Blink();
    }    
    
    public static void Blink()
    {
        IsBlinking = true;
        int i = 0;
        while (i<5)
        {
            LED.Write(!LED.Read());
            Thread.Sleep(200);
            i++;
        }
        IsBlinking = false;
    }

    The main “difficulty” is to declare correctly the interrupt port and the event handler. You can choose with the last parameter to generate the interruption only when you change from state low to high or high to low or both direction. Here it’s bi directional so on both edges. The function IntButton_OnInterrupt will be called when the sate will change. And from there the function to blink. I’ve voluntarily added some “control” code to not call the blinking function when it’s already in use.

    On the hardware part, it’s like the previous one except that I’m using here pin 12. This is because I used a more sophisticated switch. See this post.

    When you will close the switch, the light will blink 5 times so if if was off, it will finish on. Now open it again, it will blink 5 times and go back to off. So what happen if you close it and open it before you light finish to blink? will the IntButton_OnInterrupt function be called right away and because of the test to see if we are blinking or not, it will stay on the on mode after blinking 5 times? Or not?

    Answer is not! The interruption are serialized and it wait for the previous one to finish. So it will wait for the blink function to return to call the IntButton_OnInterrupt one. And that’s the mane reason why you have as a parameter the DateTime parameter. So if you did not have time to handle an interruption and want to skip it you can do it.

    Still there? Wow, that’s cool, you want some more? yes? OK, so let go for the last part: the analogic input. To illustrate this, we will need to use a temperature or light resistor. It cost couple of euros cents. They act like a resistor. The resistor vary regarding the temperature or the light.

    image

    To change a bit, let start with the hardware part. In my case I’m using a very simple light sensor acting like a resistor from 1M Ω (dark) to 100 Ω (very bright).

    In order to use it and use the most of the input range (in netduino 1024 points), you need to know the average resistance which can be calculated like this: R = √(MaxR x MinR) = √(1M x 100) = 10K Ω

     

    image

    We will use the following simple electronic schema to measure the variance of the light sensor. Again, all what you need as an electronic knowledge is U = RxI

    The analogic input Voltage = 3.3/(1+R/RL).

    So it will vary from 0.0323V (very bright) to 3.23V (dark). The medium value will be 1.5V and will be attained when the light sensor will be at its mid point resistance our famous 10K ohms.

     

     

     

    Now, lets go for the code:

    public static void ReadAnalogic()
    {
        SecretLabs.NETMF.Hardware.AnalogInput lightSensor 
    = new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0); //lightSensor.SetRange(0, 100); int lightSensorReading = 0; while (true) { lightSensorReading = lightSensor.Read(); Debug.Print(lightSensorReading.ToString()); Thread.Sleep(500); } }

    We create an AnalogicInput object. All those classes are different depending on the board you are using. But they are working almost the same way. The idea is to open a pin as analogic, setup a range for the values so it makes more easy to read a data and avoid you to do the transformation. So rather than having a 0 to 1024 value, you can directly get a –25 to 120 value if you want (for a temperature sensor for example).

    Reading the value is quite easy, just use the Read property and you’ll get the transformed value. In my case, for the example, I’m just doing a loop. In reality, it will be much better to use a timer for example. To know how to use timer, just read one of my previous article.

    This is it for this long explaining how to to use the basics IO in NETFM with a netduino board. Enjoy the electronic part! More to come Sourire I had a bit of time to write this one on my way back from Dubai in a nice A380.

  • Laurent Ellerbach

    Securing web server with login and password on .NET Microframework

    • 1 Comments

    If you want to expose your .NET Microframework web server on the Internet you better have to make sure it is protected. Even if you keep the URL secret, it will not stay secret Sourire it’s not a good way to protect it! A better way if you have to expose it is to use a login and a password. Still not the best way but reasonably ok. To add more security, use https on your board. But if you are using a netduino board like me, the https web server is a big too big and will not fit. So I’ve decided to use login/password.

    the good news is that you already have classes to be able to implement a login and password very easily. First read this post to understand how to implement a web server. In the main function ProcessClientGetRequest, just add at the beginning of the function the following code:

    string strResp = "<HTML><BODY>netduino sprinkler<p>";
    bool IsSecured = false;
    if (request.Credentials != null)
    { // Parse and Decode string.
        Debug.Print("User Name : " + request.Credentials.UserName);
        Debug.Print("Password : " + request.Credentials.Password);
        // if the username and password are right, then we are authenticated
        if (request.Credentials.UserName == MyLogin && 
    request.Credentials.Password == MyPassword) { IsSecured = true; } } //if not secured display an error message. And return the function if (!IsSecured) { strResp += "<p>Authentication required<p>Invalid login or password"; response.StatusCode = (int)HttpStatusCode.Unauthorized; response.Headers.Add("WWW-Authenticate: Basic realm=\"netduino sprinkler\""); strResp += "</BODY></HTML>"; byte[] messageBody = Encoding.UTF8.GetBytes(strResp); response.ContentType = "text/html"; response.OutputStream.Write(messageBody, 0, messageBody.Length); return; }

    The IsSecured boolean is there to check if the login and password are valid. by default it is set at false. Then the request.Credentials contains the login credentials. If they are not null, you can just check if they are the right ones. UserName contains the user name and guess what, Password contains the password. Not rocket science there Sourire just compare them with the one you want to use. By default the authentication type is basic. So login and password are send in clear mode. Not the most secure but unfortunately like most of the internet protocol still use for mail like POP and other protocols like that. Again, to get more protection, use https if you can on your board.

    .NET Micro framework web server object also support Windows Live authentication. As I’m doing this code in a plane from Moscow to Dubai, quite hard to test it!

    request.Credentials.AuthenticationType = AuthenticationType.Basic;
    request.Credentials.AuthenticationType = AuthenticationType.WindowsLive;

    Those are the 2 modes. If I have the opmportunity, I’ll test the Windows Live one. If anyone do the test, please let me know!

    The rest of the code is pretty straight forward, it’s just about displaying an error message with the HttpStutusCode as Unauthorized. And just return the function before the end. Very efficient to protect all site and all pages. The good news is that you will not have to authenticate to access all pages, it will be carry on from one page to another up to when you’ll close your browser and come back. I do not recommend to store any login/password on any of your pc, or device. Always type them!

    If you want to store somewhere the login and password, you can store it on the SD card of your board. If your board is store in a secure location in your house and not accessible, you may not need to crypt the login and password. And anyway if the person has access to your board controlling some equipment, it’s probably too late. But if you need, crypt it on the storing location.

    Here is a code example how to read this login and password from a file.

    if (Microsoft.SPOT.Hardware.SystemInfo.IsEmulator)
        strDefaultDir = "WINFS";
    else
        strDefaultDir = "SD";
    
    FileStream fileToRead = null;
    try
    {
        fileToRead = new FileStream(strDefaultDir + "\\" 
    + strFileProgram, FileMode.Open, FileAccess.Read); long fileLength = fileToRead.Length; Debug.Print("File length " + fileLength); //file length has to be less than 1024 otherwise, it will raise an exception byte[] buf = new byte[fileLength]; string mySetupString = ""; // Reads the data. fileToRead.Read(buf, 0, (int)fileLength); // convert the read into a string mySetupString = new String(Encoding.UTF8.GetChars(buf)); int mps = mySetupString.IndexOf(ParamSeparator); MyLogin = mySetupString.Substring(0, mps); MyPassword = mySetupString.Substring(mps + 1, mySetupString.Length - mps-1); fileToRead.Close(); } catch (Exception e) { if (fileToRead != null) { fileToRead.Close(); } //throw e; Debug.Print(e.Message); }

    strFileProgram contain the file name in which you ware storing the login and password. And ParamSeparator is a char containing a separator character between the login and password stored. So it’s a character that you will not allow to use in a login or password. So use a character like return. As it can’t be used in a login and password.

    The first couple of lines are to identify if we are running in the emulator or not. In the emulator storing access is by default in the WINFS directory. And on the netduino board in SD. Then the code is very similar to what I’ve already shown in this article. The login and password will have to be stored in a global string of the http server class. As explain in the mentioned article, you can also save those data quite easily using the same file. And you can also build a simple page to allow the user (usually you) to change this login and password. In my case I’m not doing it as I’m the only user. And if I need to change it, I can do it directly on the SD card. Of course, use a long login and a complex and long password. At least 10 character, a majuscule, a miniscule, a numeric and a non alphanumeric character. And you can consider you may be ok. But again, it’s not the most secure solution. So if you have to expose directly your board to the internet and you’ll need to access it thru the web sever, make sure you are not piloting any critical part of your house or resources.

    As always, any feedback welcome.

  • Laurent Ellerbach

    Using a light transistor sensor and a led to create a detector

    • 1 Comments

    I will give a session in French during the next French TechDays on .NET Microframework. And I’m preparing couple of demos that almost anyone with limited knowledge in electronic and limited knowledge in programming. The idea is to show cool stuff you can do at home or a kid can do. Interested in coming to my session and more? You can register there.

    This session will be about doing demos and showing how you can very easily do hardware with a netduino board and .NET Microframework. It’s quite cool as you are very close to the hardware and no OS to do things you don’t want to be done Sourire.

    The coolest thing is that I get old electronic component from old PC. I get a light sensor from a very old hard drive and I will use it in my demo of course. This light sensor was used to count the number of turn the hard drive was doing and assert the speed to make sure it will go on the right speed. This simple sensor is one led and on transistor. And it looks like this:

    WP_000188

    It’s this small black thing. Looking at the schematic, it look like this:

    image

    So we have a common ground and the transistor is used like an switch. If it gets light, it will be open, if not, it will be closed. So we basically have to light the led and plug the transistor into a digital input to look at the state of the pin.

    As the led is working with about 2V and current should be about 0,02A, I will have to use a resistor. I remember an old rule: U = RxI. Where U is the voltage (in Volt), R is the resistor (in Ohm) and I is the current (in Amperes). I have 3.3V and 5V alimentation present on the board. I choose to use the 3.3V. So to get the resistor needed, I need to apply a simple math:

    R = (3,3 – 2)/0,02 = 65 Ohms

    Looking at couple of resistors I have, I found a 67 Ohms which will work. It’s anyway not really precise. So I plug the resistor into the 3.3V, add the 67 Ohms resistor, then the Led. The black cable on the ground. And I plugged the yellow one into the Digital IO 12 on my board.

    To have something cool, I’m using a led which I plugged also into a Digital IO, the number 0. And the same formula apply to calculate the resistor and the same resistor has to be used, the pin are 3.3V (5V tolerant).

    Now, the very simple code to see something happening is here:

    public static void Main()
    {
        InputPort Button;
        OutputPort LED;
    
        LED = new OutputPort(Pins.GPIO_PIN_D0, true);
        Button = new InputPort(Pins.GPIO_PIN_D12, false, Port.ResistorMode.PullUp);
        while (true)
        {
            LED.Write(Button.Read());
            Thread.Sleep(10);
        }
    }

    I create a Led as an OutputPort. And an InputPort for the transistor. And I do an infinite loop to check the status. And the led will reflect the status of the transistor.

    As I’m using the transistor as a switch with a high state (Port.ResistorMode.PullUp), I will have the value of True when the transistor won’t receive any light. So it mean that when I will have an object between the led (the one in front of the transistor) and the transistor, the value of the pin will be 1 and when the transistor will receive the light, it will be 0.

    Result is quite cool, I’ve done a detector with old component Sourire Back to my Lego city lighting project, I can use this to determine if a train is coming and blink a led for couple of seconds for example. And of course, I will not use the code as it is otherwise, it will only do this and nothing else! I’ll use interrupt ports to get the change of status of the port. But that’s for another post Sourire.

    More cool code and demos during my session in TechDays. And as always, don’t hesitate to give me your feedback. This time as it’s hardware, I was not able to do this into a plane. I had to do it with the board at home. Good news is I woke up early this morning so I had time to do it.

  • Laurent Ellerbach

    ASP.NET and .NET Microframework HTTP web server together (part 2/2)

    • 0 Comments

    In my previous post, I’ve explained how create a HTTP web server on a .NET Microframework Netduino board with no OS like Windows or Linux. And how to consume a kind of web service from this device from an ASP.NET application. The idea was to get setup data from the Netduino. Those data are a list of lights placed in my Lego city. And the ASP.NET application will allow to display the lights on a map and allow the user to click on a light. When clicking, the application will call the Netduino which will do the work of turning on or off the led. And that’s this part we will explain in this post.

    The function ProcessSwitch on the Netduino board is called when a URL like http://ipaddressnetduino/switch.aspx?id=0;lg=true is called. See previous post for more details on this function.

    Now the idea is to consume this in an ASP.NET page. First, we have to get the LegoLight object from the application storage. And that’s what we are doing in the first line of code of the Page_Load function. We will later detail the rest of the code.

    public partial class _Default : System.Web.UI.Page
    {
    
        public System.Collections.ArrayList myLegoLight;
        public ParamPage MyParamPage = new ParamPage();
    
        protected void Page_Load(object sender, EventArgs e)
        {
            myLegoLight = (System.Collections.ArrayList)Application.Get("LegoLight");
            int myID = -1;
            bool myLight = false;
            if (Request.Params.Count > 0)
            {
                //Is our paramater present?
                foreach(string mystr in Request.Params.AllKeys)
                {
                    if (mystr == MyParamPage.id)
                    {
                        myID = Convert.ToInt32(Request.Params.Get(MyParamPage.id));
                    }
                    if (mystr == MyParamPage.lg)
                    {
                        myLight = Convert.ToBoolean(Request.Params.Get(MyParamPage.lg));
                    }
                }
                if ((myID >= 0) && (myID < myLegoLight.Count))
                { 
                    ((LegoLight)myLegoLight[myID]).Light = myLight;
                }
            }
           
        }
    }

    There is also some code needed to display the lights on an image. I have done this code directly in the page.

    <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
        CodeBehind="Default.aspx.cs" Inherits="LegoCityWeb._Default" %>
    
    <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    </asp:Content>
    
    <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    
    <script src="/Scripts/position.js" type="text/javascript"></script>
    
        <p>
      Click the lamp to switch on or off
        </p>
    <%
        int i = 0;
        string strResp = "";
        for (i=0; i<myLegoLight.Count; i++)
        {
            LegoCityWeb.LegoLight mLegoLight;
            mLegoLight = (LegoCityWeb.LegoLight)myLegoLight[i];
            strResp += "<span style='position:absolute;margin-left:" 
    + mLegoLight.PosX + "px; margin-top:" + mLegoLight.PosY
    + "px;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>"
    ; strResp += "<a href='/" + MyParamPage.pageDefault
    + MyParamPage.ParamStart + MyParamPage.id + MyParamPage.ParamEqual
    + i + MyParamPage.ParamSeparator + MyParamPage.lg + MyParamPage.ParamEqual
    + !mLegoLight.Light + "'>"; if (mLegoLight.Light) strResp += "<img alt='" + mLegoLight.Name
    + "' border=0 width=26 height=45 src='/lampon.png'>"; else strResp += "<img alt='" + mLegoLight.Name
    + "' border=0 width=26 height=45 src='/lampoff.png'>"; strResp += "</a></span>"; Response.Write(strResp); strResp = ""; } %> <img alt="" id="MyImage" src="/ville.jpg" /> </asp:Content>

    The first part of the code is the default code created by the template. It allow to have a nice menu, the logon part. Real code starts with the script section:

    <script src="/Scripts/position.js" type="text/javascript"></script>
    

    This script is the one I’ve developed and explain in this post to display an overlay image on an image with coordinates. There are 2 functions findLeft and findTop which returns the absolute positioning of an object from the left and top part of the page. This allow to overlay images on a page using span tags with a real positioning. Again, all this explain in the previous post.

    the for loop will go thru each LegoLight object. Each object has a position on the picture in pixel. The following code is creating the necessary code to position the picture:

    strResp += "<span style='position:absolute;margin-left:" 
    + mLegoLight.PosX + "px; margin-top:" + mLegoLight.PosY
    + "px;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>"
    ;

    The next line create a link which look like http://nameoftheserver/default.aspx?id=0&lg=true. So the main page will take params. those params allow to command the lights. That’s the second part of the code from the Page_Load function. And I’ll explain it just after.

    The rest of the client page display either an image of a light on or off depending of the status.

            if (mLegoLight.Light)
                strResp += "<img alt='" + mLegoLight.Name 
    + "' border=0 width=26 height=45 src='/lampon.png'>"; else strResp += "<img alt='" + mLegoLight.Name
    + "' border=0 width=26 height=45 src='/lampoff.png'>"; strResp += "</a></span>"; Response.Write(strResp); strResp = ""; } %> <img alt="" id="MyImage" src="/ville.jpg" />

    And finally add the main image on which all light objects will be displayed by overlay.

    So back to the page load code, when the main page is called, it can contains parameters. they are “id” and “lg”. The “id” one represents the id of a LegoLight object and the “lg” one the status of the light. Which can be on (true) or off (false).

    In order to get those params, I have done the following code:

    int myID = -1;
    bool myLight = false;
    if (Request.Params.Count > 0)
    {
        //Is our paramater present?
        foreach(string mystr in Request.Params.AllKeys)
        {
            if (mystr == MyParamPage.id)
            {
                myID = Convert.ToInt32(Request.Params.Get(MyParamPage.id));
            }
            if (mystr == MyParamPage.lg)
            {
                myLight = Convert.ToBoolean(Request.Params.Get(MyParamPage.lg));
            }
        }
        if ((myID >= 0) && (myID < myLegoLight.Count))
        { 
            ((LegoLight)myLegoLight[myID]).Light = myLight;
        }

    The Request object contains a class called Params. This class includes all parameters that are in the URL (thru a GET call) and/or thru a POST and in what the browser tells on you (your language, your OS, your IP, etc). So a nice foreach can go thru all this up to find the “id” one. And convert it to a real number as all params are just strings. And it will also find the “lg” one and concerts it to a bool.

    And if the ID is a valid number, it will switch on or off the light. If no value is present, the default value will apply and it will switch off the light. When calling the Light property of the LegoLight object, remember from my last post that it is calling the Netduino hardware thru a web page to actually physically switch the physical light on and off.

    Sol here is the end of the second part. To summarize, in those 2 articles, you’ve seen how to call a web page including parameters from a .Net Microframework Netduino board, getting parameters from this same board, displaying overlay images on it, and many things like that Sourire I hope you’ve enjoy it!

  • Laurent Ellerbach

    ASP.NET and .NET Microframework HTTP web server together (part 1/2)

    • 1 Comments

    I will show in this post how to call a web page from a .NET Microframework board which has implemented a HTTP Web Server and get results from it. The idea is to do a mix of previous posts. You are more and more to follow this blog so you may now be familiar with my implementation of a Web Server on a Netduino board. If not, read first the article which explain how to create such a web server on a board with no OS like Windows or Linux. And also how to create a dynamic management page like ASP.NET or Php or Java.

    When you’ll have read it, you’ll need also to read how to read a setup file in .NET Microframework. This is used to setup the board which will pilot led to light up my Lego city.

    Once you’ve done that, you’ll also need to read the post on how to display overlay images in HTML using Javascript. Yes, I know lots or reading before starting but I don’t want to go again thru all the code. I will only focus on the “new” parts.

    First let start with 2 web pages on the Netduino board. The first one allow to switch on and off one led. The code of the function looks like:

    private static void ProcessSwitch(HttpListenerContext context)
    {
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;
        // decode params
        string strParam = request.RawUrl;
        ParamPage MyParamPage = new ParamPage();
        bool bLight = false;
        int iID = -1;
        Param[] Params = decryptParam(strParam);
        if (Params != null)
            for (int i = 0; i < Params.Length; i++)
            {
                //find both params
                int j = Params[i].Name.ToLower().IndexOf(MyParamPage.id);
                if (j == 0)
                {
                    Convert.ToInt(Params[i].Value, out iID);
                }
                j = Params[i].Name.ToLower().IndexOf(MyParamPage.lg);
                if (j == 0)
                {
                    Convert.ToBool(Params[i].Value, out bLight);
                }
            }
        // if the ID value is valid, just light up the light :-)
        string strResp = strOK;
        if ((iID != -1) && (iID < myLegoLight.Count))
        {
            ((LegoLight)myLegoLight[iID]).Light = bLight;
        }
        else
        {
            strResp = strProblem;
        }
        
        strResp = OutPutStream(response, strResp);
    }

    In previous posts, I’ve explained how to handle parameters from a web query and transform them into real value. That’s what the first part of the code is doing.

    Please note that strOK = “OK” and strProblem = “Problem”. We will need this later on on the ASP.NET side.

    if ((iID != -1) && (iID < myLegoLight.Count))
    {
        ((LegoLight)myLegoLight[iID]).Light = bLight;
    }
    else
    {
        strResp = strProblem;
    }

    Those lines just validate that the ID of the light is in the range of ID. If yes, the OK status will be send out, if no, that the problem which will be sent out. The LegoLight structure contains information on the led, a name and coordinates on a picture. All that is explained in the previous post as a pre reading Sourire

    private static void ProcessLights(HttpListenerContext context)
    {
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;
        string strResp = "";
        LegoLight mLegoLight;
        ParamPage MyParamPage = new ParamPage();
        for (int i = 0; i < myLegoLight.Count; i++)
        {
            mLegoLight = (LegoLight)myLegoLight[i];
            strResp += mLegoLight.Name + ParamSeparator;
            strResp += mLegoLight.ID.ToString() + ParamSeparator;
            strResp += mLegoLight.Light.ToString() + ParamSeparator;
            strResp += mLegoLight.Network.ToString() + ParamSeparator;
            strResp += mLegoLight.PosX.ToString() + ParamSeparator;
            strResp += mLegoLight.PosY.ToString() + strEndFile;
            strResp = OutPutStream(response, strResp);
        }
    }

    The second function is also very simple, it does just “serialize” in the “old” way all the LegoLights objects and send them thru the output which is the web page. ParamSeparator = “&” and strEndFile = “\r”. So similar to what I’ve already explain in the post on how to read (and write) a setup file.

    Of course, when you do code on a very reach and fast platform, you can serialize those object in a nice way with XML and create the schema and all what is needed to look good, nice and reading by a human. Reality is I’m using an embedded platform where resources are expensive, almost no memory is available and it runs very slowly. Just think it’s a PC from the early 1980… And you’ll be close to the reality of what the Netduino can do.

    The output looks like: mairie&0&False&1&158&59 station&1&True&1&208&300 train&2&False&1&10&10 rue&3&False&1&700&550

    It does contain a “serialized” view of the LegoLight array. Now, the question is how to consume this? Answer is: thru an ASP.NET application Sourire

    So let’s go for the code to consume this. First step is to create an ASP.NET  application. I’ve used a simple default template which contains the code to create and manage users, a default page and an about page. So all what is needed to start. First step is to create the LegoLight object.

    public class LegoLight
     {
         private string myName = "";
         private int myPosX = 0;
         private int myPosY = 0;
         private byte myNetwork = 0;
         private bool myLight = false;
         private int myID;
    
         public int ID
         {
             get { return myID; }
             set { myID = value; }
         }
    
         public string Name
         {
             get { return myName; }
             set { myName = value; }
         }
         public int PosX
         {
             get { return myPosX; }
             set { myPosX = value; }
         }
         public int PosY
         {
             get { return myPosY; }
             set { myPosY = value; }
         }
         public byte Network
         {
             get { return myNetwork; }
             set { myNetwork = value; }
         }
         public bool Light
         {
             get { return myLight; }
             set { 
                 // do call the Netduino here :-)
                 // and change the status
    
                 //Create a web client object
                 string strUri = LegoCityWeb.Properties.Settings.Default.NetduinoURL;
                 ParamPage MyParamPage = new ParamPage();
                 strUri += MyParamPage.ParamStart + LegoCityWeb.Properties.Settings.Default.NetduinoID + MyParamPage.ParamEqual + myID;
                 strUri += MyParamPage.ParamSeparator + LegoCityWeb.Properties.Settings.Default.NetduinoLight + MyParamPage.ParamEqual + value;
                 //URL will look like http://ipaddressnetduino/switch.aspx?id=0;lg=true
                 Uri MyUri = new Uri(strUri);
                 string myResponse = GetStringFromURL(MyUri);
                 if (myResponse == LegoCityWeb.Properties.Settings.Default.NetduinoOK)
                     myLight = value;
              }
    
         }
         public string GetStringFromURL(Uri mUri)
         {
             WebClient instanceHTTP = new WebClient();
             const int MAX_BUFFER = 1024;
             string myResponse ="";
             Stream returnValue;     
             try
             {
                 //call the specific URI
                 returnValue = instanceHTTP.OpenRead(mUri);
                 // read the stream. This stream can't be seek, so get every byte "manually"
                 byte[] mybuff = new byte[MAX_BUFFER];
                 int i = 0;
                 int ret = -1;
                 do
                 {
                     ret = returnValue.ReadByte();
                     //if there is nothing to read return -1. Values goes from 0 to 255
                     if (ret > 0)
                     {
                         mybuff[i] = (byte)ret;
                     }
                     else
                     {
                         mybuff[i] = 0;
                     }
                     i++;
                 } while ((ret != -1) && (i < MAX_BUFFER));        
                 //returnValue.Read(mybuff, 0, (int)returnValue.Length);
                 myResponse = System.Text.Encoding.ASCII.GetString(mybuff, 0, i-1);
                 returnValue.Dispose();
             }
             catch(Exception ex)
             {                    
                 return myResponse;                       
             }
             //close the stream
             
             return myResponse;
         }
    
     }

    Nothing really complicated here, you’ll find very basic properties to get and set the ID, the name, the network, the position. Where it gets a bit more complicated it’s for the Light property. Well, remember that when you set the property to false, the idea is to switch off the light and when on true, to switch it to on. The idea is to call the first web method we’ve just write on the Netduino board. Remember, the URL to call looks like http://ipaddressnetduino/switch.aspx?id=0;lg=true

    In the code, I’m using application setting for the URL (NetduinoURL), the name of the paramaters (both for the ID NetduinoID and light status NetduinoLight). And I build the URL with the ID of the LegoLight object and the status of the light (so True or False, will also work with 1 and 0). When it’s done, I call a function called GetStringURL. This function has the only purpose to call the URI and return as a string the result. I’ll explain the function later on. In our case, back to the beginning of the article, this function will return “OK” if everything is correct of “Problem” if not. So I just test if it’s OK or not. And set the new light status if everything works fine.

    So now, let have a look at the GetStringURL function. It does take a URI as an argument and return a string.

    WebClient instanceHTTP = new WebClient();
    const int MAX_BUFFER = 2048;
    string myResponse ="";
    Stream returnValue;     
    First step is to create the variables we will need. We will call a web page, so we need to create a WebClient object. the MAX_BUFFER constant will be used to create a buffer that will contain what is returned by the Netduino. I have limited it to 2048 as it’s the maximum number of characters that will be send. On the Netduino, the original setup file will not exceed 1024 characters. But on the response stream, it will contains the ID and the light status as True and False rather than in text. So it will be a bit longer but there is no chance that the returned page will be larger than 2048.

    the myResponse will be used to put the response text and return it. And the stream object to get the stream from the WebClient object call.

    try
    {
        //call the specific URI
        returnValue = instanceHTTP.OpenRead(mUri);
        // read the stream. This stream can't be seek, so get every byte "manually"
        byte[] mybuff = new byte[MAX_BUFFER];
        int i = 0;
        int ret = -1;
        do
        {
            ret = returnValue.ReadByte();
            //if there is nothing to read return -1. Values goes from 0 to 255
            if (ret > 0)
            {
                mybuff[i] = (byte)ret;
            }
            else
            {
                mybuff[i] = 0;
            }
            i++;
        } while ((ret != -1) && (i < MAX_BUFFER));        

    The next part of the code open the URI and place the result in the stream returnValue. It’s a synchronous call but it will be quick as the Netduino will only return text. So no need here to do an asynchronous call which will be necessary if you have large amount of data to read.

    Now, the specificity with the stream we just get is that it is not seekable. So the only way I found to get the data is to pull every single char after the other. The function ReadByte allow this kind of read and return a byte (so a value between 0 and 255). It return –1 in case of problem. The “do while” loop if here to read the entire buffer. And of course, when you start manipulating stream, you better have to use a try catch section.

    So either when the buffer is full or when you’ve reach the end of the stream, the mybuff byte array will contain all the stream. Next step is to convert if to a string.

    myResponse = System.Text.Encoding.ASCII.GetString(mybuff, 0, i-1);

    That’s what this function is doing for you. In the same class, you find also a function to convert from string to a char array and more. And the conversion will be done only for the right amount of read data.

    So here it is for the LegoLigh object. A bit different that the one on the Netduino but only for the Light part. Which on the Netduino call hardware function to actually light up leds.

    Now it still does not answer the question on how to consume the “serialized” LegoLight array returned by the Netduino. For this, we will need also to read a stream and convert it to a string and “deserialize” the string to rehydrate the objects. The best place to do that is when the web application starts. It suppose that the Netduino is already started. If not, it’s just about adding a reinitialisation fonction which will basically call again the same code. It may be needed after a cold Netduino boot. It can also be checked by the main ASP.NET application on a regular basis like every day, week or hour. We’re not there for the moment.

    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup
        LegoLight mLegoLight = new LegoLight();
        string strUri = LegoCityWeb.Properties.Settings.Default.NetduinoURLLight;
        ParamPage MyParamPage = new ParamPage();
        //URL will look like http://ipaddressnetduino/lights.aspx
        Uri MyUri = new Uri(strUri);
        string mySetupString = mLegoLight.GetStringFromURL(MyUri);
        int i = mySetupString.IndexOf(MyParamPage.EndFile);
        string mySubstring = "";
        string[] myParam;
        int j = 0;
        int inc = 0;
        try
        {
            char[] mSeparator = MyParamPage.ParamSeparator.ToCharArray();
            while ((i < mySetupString.Length) && (i != -1))
            {
                //split the substring in 3
                mySubstring = mySetupString.Substring(j, i - j);
                myParam = mySubstring.Split(mSeparator);
                mLegoLight = new LegoLight();
                mLegoLight.Name = myParam[0];
                int myint = 0;
                myint = Convert.ToInt32(myParam[1]);
                mLegoLight.ID = myint;
                mLegoLight.Light = Convert.ToBoolean(myParam[2]);
                //Convert.ToInt(myParam[1], out myint);
                myint = Convert.ToInt32(myParam[3]);
                mLegoLight.Network = (byte)myint;
                myint = Convert.ToInt32(myParam[4]);
                //Convert.ToInt(myParam[2], out myint);
                mLegoLight.PosX = myint;
                myint = Convert.ToInt32(myParam[5]);
                //Convert.ToInt(myParam[3], out myint);
                mLegoLight.PosY = myint;
                myLegoLight.Add(mLegoLight);
    
                //next string
                j = i + 1;
                if (j < mySetupString.Length)
                    i = mySetupString.IndexOf(MyParamPage.EndFile, j);
                else
                    i = -1;
                inc++;
            }
            Application.Add("LegoLight", myLegoLight);
        }
        catch
        { 
        
        }
    }

    The code will seat in the Application Start function. This is the first method called when the ASP.NET application starts. So the perfect moment to add those kind of initialization.

    Same as for the LegoLight object for the Light method, it starts with the creation of a URI and the call of the specific page which will return the serialized object. The deserialization is not too complex, it’s about splitting the string. First by finding the “\r” character and then the separators “&”. It’s quite artisanal but it’s perfectly working. Then a simple conversion for int and bool allow to populate the LegoLight object and add it to the Array. And finally, this array is stored into the Application storage to be used later.

    And that’s it for the first part of this article. In the second part, we will see how to call the method to change the light and display this in a nice and sweet ASP.NET page. As always, I’m coding in planes and also write articles in planes with no Internet connection. I don’t know why but I enjoy coding in planes with no way to find better code than the one I write. I’m just a marketing director writing code Sourire. And as always, feedback welcome. Thanks for one I already received, it motivates me to continue. And thanks also for being more and more to read this blog.

Page 1 of 5 (122 items) 12345