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

    Lighting my Lego city using .NET Microframework

    • 4 Comments

    Now I have created a software to pilot sprinklers, I want to be able to pilot my Lego city and light it. I know my sprinkler project is not over as I still need to work on the hardware. I will do it over the winter and try to find someone to help me. This new project looks simpler for me as it will basically only be couple of led. So it can be directly plugged to the netduino board.

    I have quite a big Lego city as you can see in this picture with 2 trains, a modern city, an old city, an airport, couple of rail stations.

    For those who may not have guess, I’m a Lego fan, I have more than 650 official Lego sets from 1970+ to now. Not all are build, some are just used for spare parts to build other kind of constructions. And I have also hundreds of kilos of brick at home which allow me to build whatever I want. You can have a look at part of the collection here.

    Same as for the sprinkler project, the idea is to be able to switch some part on automatically, at night for example, and switch them on and off also manually. In order to reuse the work I’ve done, I will create a similar project with and http web server (like IIS or Apache running on Windows or Linux), dynamic pages (like ASP.NET, php or Java) with parameters. I’ve already develop a web server I will be able to reuse and the management for dynamic input.

    My idea this time is to be able to display a web page with pictures of the city and specific points on the pictures that will represent the light to switch on and off. clicking on them will change the color of the points and switch the light accordingly.

    In a longer term, I will try to pilot also the train lights and the rail switch. That will need a bit more electronic but is very easy to do in term of code. So probably that the code will exist before the electronic as for the sprinkler project. I will try also in this project to use the SD card to store the picture of the city and the points coordinate to be displayed. So a kind of setup file. I’ve already try to play with the SD card but with limited success. I don’t know from where the problem is coming from. I use couple of different cards and I always get errors but never the same. So I think the problem is coming from the hardware.

    So let see where this project will go Sourire

  • Laurent Ellerbach

    .NET Microframework on RaspberryPi (Part 1)

    • 4 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

    Writing a generic ASP.NET handler to return an image and control the image

    • 1 Comments

    In one of my project, I want to integrate the picture from an IP camera to a web site. The idea is to be able to put a IP camera in my Lego room and see it for real. Especially to be able to control it. this project is linked to the one to light my Lego city. Instead of having the static image of the city, I want to be able to show the real time image. For this project, I’m using a netduino and .NET Microframework.

    Most IP camera do propose a simple URL where you can get the image. So it is very easy to integrate. But what if you want to control when to display the picture? Let say you don’t want to display the picture over night or just in small period of time? Or you want to dynamically add something to the picture like a layer? Well, IP camera are not smart enough to do it. So you’ll have to write some code.

    In ASP.NET you cant easily write a generic handler with the .ashx extension. that’s what I’ll do. And I’ll do it in VB.NET, that will change from my previous post that I did in C#. And no, I won’t do it in C++, php or Java Tire la langue. Yes, I do love VB too. Not only C#. As started developing a very long ago when the only thing you had on a PC was BASICA, the BASIC that was implemented in the IBM PC ROM. My father had a PC at home he was using for his own business.I was allow to use it but as I did not get any floppy disk, the only thing I was able to do was coding. And that’s at this time at 10 I started to code… in BASIC. and since then I never stopped coding Sourire 

    The simple code is the following one:

    <%@ WebHandler Language="VB" Class="Image" %>
    
    Imports System
    Imports System.Web
    Imports System.Net
    Imports System.IO
    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Drawing.Drawing2D
    
    Public Class Image : Implements IHttpHandler
        
        Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
            context.Response.ContentType = "image/jpeg"
            context.Response.AddHeader("Cache-Control", 
    "private,must-revalidate,post-check=1,pre-check=2,no-cache") Dim instanceHTTP As New WebClient Dim MyUri As New Uri("http://yourcameraurl/image.jpg") Dim returnValue As Stream Try returnValue = instanceHTTP.OpenRead(MyUri) Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue) MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg) MyImage.Dispose() Catch ex As Exception context.Response.Write("Error") End Try End Sub Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class

    On top the page, you have to declare that it’s a WebHandler and implement IHttpHandler. When you’ve done that, add the ProcessRequest function as following:

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

    And also the read only property IsReusable. This function basically allow you to control if you want the ProcessRequest function to be reusable without executing the code or not. Here, the idea is to refresh the image each time the function is called so the property will return false.

    The ProcessRequest function gives you a HttpContext object. This object allow you to get many information like the brower type, the IP request address and more. But it also allow you to write in the response object. And that’s what interest us here as we want to send back an image.

    context.Response.ContentType = "image/jpeg"
    context.Response.AddHeader("Cache-Control", "private,must-revalidate,post-check=1,pre-check=2,no-cache")

    Those 2 just set the content type as an image so the browser will know how to interpret the content before having it at all. It does this interpretation automatically based on the extension of the file usually even if the type is not set. But here, it is mandatory to define as the extension of you file is .ASHX. And is it not interpreted as an image by any browser Sourire and the .ASHX can virtually return anything, it can be images, text, videos, PowerPoint, Excel file, Word docs, zip or whatever you want. So don’t forget this line! Still the browser (at least Internet Explorer Sourire) is smart enough to figure out that when you are in the “Error” returned in the stream is text and not a jpg…

    the second line is about adding a header. Here, I’m not really sure I do it correctly but I try to specify that the browser can’t cache the image as I want always a fresh image.

            Dim instanceHTTP As New WebClient
            Dim MyUri As New Uri("http://yourcameraurl/image.jpg")
            Dim returnValue As Stream

    The instanceHTTP variable will be used to download the image from the web cam. It’s a WebClient which allow to do this kind of operation. It can be done synchronously or asynchronously.

    The MyURI is used to create the URI that will be used to download the picture. So put in the string the address of your webcam. It is quite easy to find, just open your webcam in a browser, usually it display a page which includes the picture of your image. Right click on the image and you get the URL.

    Then we will need a stream object to put the image in and resend to the response object. that’s what returnValue is.

            Try
                returnValue = instanceHTTP.OpenRead(MyUri)
                
                Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)
                            
                MyImage.Save(context.Response.OutputStream, 
    System.Drawing.Imaging.ImageFormat.Jpeg)MyImage.Dispose() Catch ex As Exception context.Response.Write("Error") End Try

    I know you are a good developer so I know when you are trying to access critical resources or resources that may not be present that you are using a try catch section. Good, you are a great developer Sourire. The fact is that trying to download a picture from a webcam may not work. The webcam may be down, your kids may have switch it off or your cat or your mother or whatever can happen.

    returnValue = instanceHTTP.OpenRead(MyUri)

    The 3 variables created previously are used in this line of code. It does open a stream (returnValue) from the WebClient (instanceHTTP) which has a URI (MyURI). That’s done, we are ready to download the picture from the camera.

    Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)

    So I create an Image object which I get from the camera thru the function FromStream. On this image, I can do whatever I want. Add text, change the size, colors or do any manipulation.

    MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)

    Here, I just save the image as a jpeg in the Response object. And I don’t forget to dispose the image as I don’t need it anymore.

    And that’s it! And you can image returning video or file you have created on the flight. Or pages or whatever you want. It is as simple to use handlers in ASP.NET. This implementation as it is as not really a usage. It is much simple to directly use the address of the camera. The only usage you can see is to secure your internal network and the access to the camera. By doing this you are impersonalizing the access to the camera. It is view as a black box from your web server.

    I’ll try to do couple of more post to show examples on how you can create thumbnails on the flight using this technic or maybe how you can restrict access regarding hours. I’m just a marketing guy with a technical background doing code in planes and enjoying it Sourire So any feedback on the code an those articles is welcome. And I see in my stats you are more and more to read them!

  • 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 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

    netduino board: geek tool for .NET Microframework

    • 0 Comments

    In the past, long time ago, I’ve been a developer. I loved to develop low level code like drivers. And I love embedded and robots and all those stuff. So I have a natural attraction for .NET Microframework. Of course I know it was existing but I never really touch it. And discussing with Pierre Cauchois, he told me he bought a netduino board and automate his cooler!

    I had a look at it and just figure that was exactly what I needed to start my automation sprinkler project! So I bought the netduino plus version with the micro sd card reader and the network connection. So 50€ later and couple of days I’ve received this gadget Sourire

    What I love with netduino is that it’s an open source design, really simple and efficient, the community is really active and it has all what I needed in terms of IO. And of course, I’ll be able to reuse my .NET C# skills. OK, last time I’ve coded in C# was 1 year ago to automate my CANON EOS and be able to control it. But after 2 hours of code, C# skills come back very fast Sourire And good news with .NET Microframework is that the number of class is quite small! so it’s very easy to understand, very efficient classes and pretty much all what you need.

    So I’ve started by downloading and installing all the SDK (I’m using Visual Studio Ultimate but it’s working with express versions). and downloaded the first example to make the embedded led blinking. And é minutes later, it was working Sourire At this time I was an happy geek Rire

    So I started to look at other samples that are available and played with the HHTPServer one. And decided to derive from this project to build my own pages and program my sprinklers. On the other side, I’ve done quite a bit retro engineering on my sprinklers (Gardena model). they are bi stable electro valve using 9V small impulsions. So I know I have to use 2 digital output to pilot open and close for each sprinkler. And I’ll first concentrate and the soft and then on the hardware. By the way, the hardware question is still open, so if anyone want help, I’ll appreciate it.

    When searching if someone already did this, I found Mike Linnen  who has done an amazing integration with Windows Azure and Windows Phone 7. check it, it’s really cool!

    In the next post, I’ll go thru couple of lines of code!

  • 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.

  • Laurent Ellerbach

    Les outils de gestion d’énergie/alimentation dans Windows Vista et Windows 2003

    • 1 Comments

    Suite aux Microsoft TechDays et à l’offre que notre partenaire ACER a fait sur les machines qu’ils nous ont prêté, j’ai acheté un ACER Power 2000. Très bonne machine, très compacte et très sympa. Elle ne fait pas un bruit, fonctionne super bien avec Vista, bref le bonheur.

    Le seul truc, c’est que j’ai joué avec les paramètres d’énergies (et pas à travers les outils de vista) mais à travers un soft qui m’avais permis de régler des problèmes de veille avec Windows XP. En gros, je n’aurais pas dû (c’est comme toujours, on se dit qu’il ne faut pas le faire mais on le fait quand même). Et Murphy obligeant, je ne me suis aperçu des problèmes engendrés que bien plus tard. Trop tard pour faire un point de restauration. Le problème n’est pas bien compliqué : mon ordinateur ne se met pas en veille correctement.

    Evidemment, j’ai commencé par regarder dans les paramètres d’alimentation du panneau de configuration.  Tout semblait correct, le mode « normal » était sélectionné par défaut, les veilles étaient positionné correctement. Alors d’où venait le problème ?

    Je me suis donc mis à la recherche d’information. A travers http://www.live.com, je suis rapidement arrivé sur la page http://www.microsoft.com/whdc/system/pnppwr/powermgmt/default.mspx et j’ai lu la présentation du WINHEC. C’est un top événement qui a lieu uniquement aux US à destination des développeurs et constructeurs de hardware. A ne pas rater pour tous ceux qui développent drivers, BIOS et autres logiciel de bas niveau. Un peu de lecture rapide et je tombe sur une présentation remarquablement bien faite : Power Management in Windows Vista [WinHEC 2006; 459 KB]. J’y trouve notamment les informations sur les différents modes de veilles, le nom d’un outil en ligne de commande « powercfg.exe », que les infos sont stockées dans le registre sous HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power et aussi que Vista supporte la programmation des modes de veille par GPO. Bref, tout ce qu’il faut pour que je trouve d’où vient le problème.

    Je me lance donc à l’attaque de l’outil powercfg avec la base de registre ouverte à côté histoire de voir. La doc complète de powercfg se trouve en tapant « powercfg /? » (dans la langue de l’OS) sinon sur le site TechNet ici (en anglais). L’outil permet en fait d’avoir les principales infos et effectuer des modifications de base. La base de registre est surtout constituée de GUID avec des valeurs de paramétrage. L’utilisation massive de GUID rend la lecture humaine assez difficile.

    La base de registre donne ça :

    PowerSettings base de registre

    Et chaque sous système ressemble à ça (pas super lisible en général, là, c’est assez facile, il s’agit du disque) :

    PowerSettings base de registre - détail

    Du coup, j’ai utilisé la commande pour avoir la description de tous les GUID : powercfg /aliases

    Ca donne la sortie suivante qui fait le lien entre le nom court du périphérique et le GUID

    a1841308-3541-4fab-bc81-f71556f20b4a  SCHEME_MAX

    8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c  SCHEME_MIN

    381b4222-f694-41f0-9685-ff5bb260df2e  SCHEME_BALANCED

    fea3413e-7e05-4911-9a71-700331f1c294  SUB_NONE

    238c9fa8-0aad-41ed-83f4-97be242c8f20  SUB_SLEEP

    29f6c1db-86da-48c5-9fdb-f2b67b1f44da  STANDBYIDLE

    9d7815a6-7ee4-497e-8888-515a05f02364  HIBERNATEIDLE

    94ac6d29-73ce-41a6-809f-6363ba21b47e  HYBRIDSLEEP

    b7a27025-e569-46c2-a504-2b96cad225a1  CRITICALSLEEP

    7516b95f-f776-4464-8c53-06167f40cc99  SUB_VIDEO

    3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e  VIDEOIDLE

    90959d22-d6a1-49b9-af93-bce885ad335b  VIDEOADAPT

    0012ee47-9041-4b5d-9b77-535fba8b1442  SUB_DISK

    6738e2c4-e8a5-4a42-b16a-e040e769756e  DISKIDLE

    4f971e89-eebd-4455-a8de-9e59040e7347  SUB_BUTTONS

    7648efa3-dd9c-4e3e-b566-50f929386280  PBUTTONACTION

    96996bc0-ad50-47ec-923b-6f41874dd9eb  SBUTTONACTION

    5ca83367-6e45-459f-a27b-476b1d01c936  LIDACTION

    a7066653-8d6c-40a8-910e-a1f54b84c7e5  UIBUTTON_ACTION

    e73a048d-bf27-4f12-9731-8b2076e8891f  SUB_BATTERY

    637ea02f-bbcb-4015-8e2c-a1c7b9c0b546  BATACTIONCRIT

    9a66d8d7-4ff7-4ef9-b5a2-5a326ca2a469  BATLEVELCRIT

    d8742dcb-3e6a-4b3c-b3fe-374623cdcf06  BATACTIONLOW

    8183ba9a-e910-48da-8769-14ae6dc1170a  BATLEVELLOW

    54533251-82be-4824-96c1-47b60b740d00  SUB_PROCESSOR

    bc5038f7-23e0-4960-96da-33abaf5935ec  PROCTHROTTLEMAX

    893dee8e-2bef-41e0-89c6-b55d0929964c  PROCTHROTTLEMIN

    68f262a7-f621-4069-b9a5-4874169be23c  PROCIDLE

    bbdc3814-18e9-4463-8a55-d197327c45c0  PROCPERF

    0e796bdb-100d-47d6-a2d5-f7d2daa51f51  CONSOLELOCK

    501a4d13-42af-4429-9fd1-a8218c268e20  SUB_PCIEXPRESS

    ee12f906-d277-404b-b6da-e5fa1a576df5  ASPM

    Ensuite, il est possible de vérifier que chaque valeur ACSettingIndex (sur secteur) et DCSettingIndex (sur batterie) est bien positionnée en fonction de chaque périphérique.

    Quand au paramétrage du réveil de l’ordinateur en fonction du périphérique, cela se fait facilement au travers de la commande « powercfg -devicequery wake_armed » qui permet de lister tous les périphériques qui permettent de réveiller le système. Ensuite, il est possible de faire un « powercfg -devicedisablewake "Microsoft USB IntelliMouse Explorer" » pour désactiver la souris par exemple (attention, le nom des périphériques est souvent dans la langue locale de l’OS). Et pour l’activer : « powercfg -deviceenablewake "Microsoft USB IntelliMouse Explorer" »

    Après avoir joué un peu, je me suis aperçu que tout était à peu près bien paramétré,  mais que mon problème venait d’un mauvais paramétrage du mode de mise en veille entre mon BIOS (positionné en S1) et le paramétrage de Vista (positionné en S3). Le positionnement en S3 a été fait par l’appli que j’avais utilisé.

    Mais je ne me suis pas arrêté là et j’ai testé le paramétrage des modes veilles par les GPO. Un petit coup de gpedit.msc et la console se lance. Rien de bien compliqué, en quelques cliques, on trouve les infos pour la gestion d’alimentation :

    GPO base de registre gestion d'alimentation

    L’intérêt de l’utilisation des GPO pour gérer les modes de veilles est qu’elle est prioritaire sur la configuration de l’utilisateur. Du coup, cela évite à la maison avec les enfants ou au boulot avec les utilisateurs d’avoir les paramétrages modifiés.

    J’ai donc configuré les principaux paramètres directement dans la GPO et maintenant, je suis tranquille J

     

  • Laurent Ellerbach

    Implementing a simple HTTP server in .NET Microframework

    • 4 Comments

    To follow my previous posts, I’ve started to implement a simple HTTP server in my netduino using .NET Microfamework. I have to admit it was quite easy as there is a HTTP Server example in the samples. I was very impressed that with no OS so no Windows, no Linux, no Mac or any DOS or whatever OS, you can do high level code, create a Web Server in about 2 hours. I haven’t seen something comparable using Java, native C or other languages. There may be ways but here, all the framework is designed to be able to handle any kind of networking, there is even multithreading. I’ll use multithreading in a future post to show how to handle periodic calls.

    As I would not use all the functions, I’ve started to simplify the code and kept only what I needed.

    So I just kept couple of functions:

    • public static void StartHttpServer()
    • internal static void RunServer(string prefix)
    • static private string GetPathFromURL(string URL)
    • private static void ProcessClientGetRequest(HttpListenerContext context)
    • static void SendFileOverHTTP(HttpListenerResponse response, string strFilePath)
    • class PrefixKeeper

    I will not used any post method, so I removed it from the code. I removed also the certificate part because I won’t use HTTPS and removed the secure part as I won’t also use it. It needs to clean a bit the code but nothing really too complicated.

    I wanted to use parameter in the URL. So have requests like http://siteweb/page.ext?param1=value1;param2=value2

    In order to do that, I’ve created a very simple class which associate on parameter and one value. Nothing really to comment here, it’s a very classic class. I let the set and get properties in this class as it may be use in read and write. Both parameters and values are string.

    public class Param
            {
                private string myName = "";
                private string myValue = "";
    
                public string Name
                {
                    get { return myName; }
                    set { myName = value; }
                }
    
                public string Value
                {
                    get { return myValue; }
                    set { myValue = value; }
                }
    
                public Param()
                {
                    myName = "";
                    myValue = "";
                }
            }

    In the sample, there is nothing to decrypt such a URL. So I’ll need to function to decrypt the URL and return a table with parameters and the associated values.

    As I want to have clean code (or as clean as possible Sourire), I’ve defined 3 chars constant for the various separators.

    const char ParamSeparator = ';';
    const char ParamStart = '?';
    const char ParamEqual = '=';

    private static Param[] decryptParam(String Parameters)
    {
        Param[] retParams = null;
        int i = Parameters.IndexOf(ParamStart);
        int j = i;
        int k;
        if ( i> 0) 
        {
            //look at the number of = and ;
            
            while ((i < Parameters.Length) || (i == -1))
            {
                j = Parameters.IndexOf(ParamEqual, i);
                if (j > i)
                {
                    //first param!
                    if (retParams == null)
                    {
                        retParams = new Param[1];
                        retParams[0] = new Param();
                    }
                    else
                    {
                        Param[] rettempParams = new Param[retParams.Length+1];
                        retParams.CopyTo(rettempParams, 0);
                        rettempParams[rettempParams.Length-1] = new Param();
                        retParams = new Param[rettempParams.Length];
                        rettempParams.CopyTo(retParams, 0);
                    }
                    k = Parameters.IndexOf(ParamSeparator, j);
                    retParams[retParams.Length - 1].Name = Parameters.Substring(i + 1, j - i - 1);
                    //case'est la fin et il n'y a rien
                    if (k == j)
                    {
                        retParams[retParams.Length - 1].Value = "";
                    } // cas normal
                    else if (k > j)
                    {
                        retParams[retParams.Length - 1].Value = Parameters.Substring(j + 1, k - j - 1);
                    } //c'est la fin
                    else
                    {
                        retParams[retParams.Length - 1].Value = Parameters.Substring(j + 1, Parameters.Length - j - 1);
                    }
                    if (k > 0)
                        i = Parameters.IndexOf(ParamSeparator, k);
                    else
                        i = Parameters.Length;
                }
            }
        }
        return retParams;
    }

    The code here is not very complex. It looks first at the start parameter. Here, it’s the question mark (? ParamStart) then it finds the separator equal mark (= ParamEqual) and it finished by the separator (; ParamSeparator). Couple of cases if we are at the end for example as there is usually no separator.

    I’m not sure it’s the smartes way to do it but it’s working, it’s pretty robust and it’s been working with many various URL and cases. I’ve chosen to return a table as it’s easy to implement and easy to use. It’s pretty simple in .NET Microframework.

    You just has to be careful as depending on the platform you are using the size of the tables are limited. In the case of netduino, it’s a maximum 1024 elements. That’s also the limit size for strings. No impact here as we can consider (never consider anything in code Sourire) that a URL will be less than 1024 parameters as the string used will of course of a maximum of 1024 characters.

    In order to have clean code, I’ve also define couple of parameters and page names in a read only class.

    public class ParamPage {
        public string year { get { return "year"; } }
        public string month { get { return "month"; } }
        public string day { get { return "day"; } }
        public string hour { get { return "hour"; } }
        public string minute { get { return "minute"; } }
        public string duration { get { return "duration"; } }
        public string spr { get { return "spr"; } }
        public string pageProgram { get { return "program.aspx"; } }
        public string pageListPrgm { get { return "listprg.aspx"; } }
        public string pageCalendar { get { return "calendar.aspx"; } }
        public string pageSprinkler { get { return "sprinkler.aspx"; } }
    }

    It defines all my parameters, name of the pages I’ll use. So in code, I’ll use this class to make sure I’ll always use the right element and don’t mix up my parameters. It will also be the same name use for all pages when needed.

    As you’ve seen, the decrypt parameter function return a string value. In your code, you may want to convert it to int, float, bool or other numeric values. .NET Microframework does not provide any convert class as the full framework. So you’ll to do it by hand Sourire Not quite hard and you’ll be able to keep this class for other development.

    public class Convert
     {
         public static bool ToFloat(string s, out float result)
         {
             bool success = true;
             int decimalDiv = 0;
             result = 0;
             try
             {
                 for (int i = 0; i < s.Length; i++)
                 {
                     if (s[i] == '.' && decimalDiv == 0)
                         decimalDiv = 1;
                     else if (s[i] < '0' || s[i] > '9')
                         success = false;
                     else
                     {
                         result = result * 10;
                         decimalDiv = decimalDiv * 10;
                         result += (int)(s[i] - '0');
                     }
                 }
                 result = (float)result / decimalDiv;
             }
             catch
             {
                 success = false;
             }
             return success;
         }
    
         public static bool ToInt(string s, out int result)
         {
             bool success = true;
             result = 0;
             try
             {
                 for (int i = 0; i < s.Length; i++)
                 {
                         result = result * 10;
                         result += (int)(s[i] - '0');
                 }
             }
             catch
             {
                 success = false;
             }
             return success;
         }
    
         public static bool ToBool(string s, out bool result)
         { 
             bool success = true;
             result = false;
             try
             {
                 if ((s == "1") || (s.ToLower() == "true"))
                     result = true;
             }
             catch
             {
                 success = false;
             }
             return success;
         }
     
     }

    The code is very simple too. I’ve prefer to handle in the class a try catch and return a success value. I feel more comfortable coding like that but if you want to make it more simpler and faster, just don’t use a try catch and handle it in a higher level. The conversion for int will return funky numbers if you don’t have only decimal in the string and same for float. I’m not looking first if all are numeric if the min and max values are correct. It’s just fast and easy way to convert.

    For the bool conversion, I’ve decided to only validate the true which can be represented as 1 or true. Anything else will just be false. So here false is anything but true.

    Now to use the decrypt function and associate couple of values, here is a complete example. with the request.RawUrl you can get the URL so a string like calendar.aspx?year=2011;month=9;spr=0

    HttpListenerRequest request = context.Request;
    HttpListenerResponse response = context.Response;
    // decode params
    string strParam = request.RawUrl;
    ParamPage MyParamPage = new ParamPage();
    int intMonth = -1;
    int intYear = -1;
    int intSprinkler = -1;
    Param[] Params = decryptParam(strParam);

    Here you’ll get Params as a table of 3 elements. First couple will be year and 2011, second month and 9 and third spr and 0. All as strings. Now you’ll have to convert those string into values and then use them in your code.

    if (Params !=null)
        for (int i = 0; i < Params.Length; i++)
        {
            //on cherche le paramètre strMonth
            int j = Params[i].Name.ToLower().IndexOf(MyParamPage.month);
            if (j == 0)
            {
                Convert.ToInt(Params[i].Value, out intMonth);
            }
            j = Params[i].Name.ToLower().IndexOf(MyParamPage.year);
            if (j == 0)
            {
                Convert.ToInt(Params[i].Value, out intYear);
            }
            j = Params[i].Name.ToLower().IndexOf(MyParamPage.spr);
            if (j == 0)
            {
                Convert.ToInt(Params[i].Value, out intSprinkler);
            }
        }

    At the end, you’ll get intMonth = 9, intYear = 2011 and intSprinkler = 0.

    Last but not least, to call a function with a name and parameters you’ll need to do it in the private static void ProcessClientGetRequest(HttpListenerContext context) function from the sample.

    HttpListenerRequest request = context.Request;
    HttpListenerResponse response = context.Response;
    
    ParamPage MyParamPage = new ParamPage();
    
    string strFilePath = GetPathFromURL(request.RawUrl);
    
    string strCalendar = "\\" + MyParamPage.pageCalendar;
    // if page calendar.aspx
     if (strFilePath.Length >= strCalendar.Length)
     {
         if (strFilePath.Substring(0, strCalendar.Length).ToLower() == strCalendar)
         {
             ProcessCalendar(context);
             return;
         }
     }

    So basically, the idea is to see if the name of the page is the one used at the beginning of the URL string. If yes, it calls a specific function and gives it the context object. From there, you can use the previous code to decode your URL and analyze your parameters.

    So to summarize, with couple of more functions, you are now able to pass parameters un a URL and decrypt them. For me, that’s what I wanted to do as it’s very easy to use to generate URL but also call specific URL in code. If you have better way to do all of this, just let me know, I’m just a marketing guy doing code Sourire

  • 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

    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

    J’ai hacké mon onduleur ou le reverse engineering de protocoles de communication (part 1)

    • 15 Comments

    C’est un titre un peu long mais bon, il exprime le fond de mon problème : j’ai acheté un onduleur (un Belkin) pour mettre sur mon serveur et un de mes PC à la maison. Par contre, faudra être un peu patient car il va y avoir plusieurs post sur le sujet.

    Le truc, c’est que l’application de gestion livrée avec est… comment dire… sans dire de gros mots… un peu vieillissante et inutilisable pour faire de l’administration. Une vieille appli au look de la fin des années 90, pas d’accès à distance, pas de SNMP, pas de page Web, bref rien :-(. Pour ne pas polémiquer, je préfère ne pas mettre de capture d’écran. Mais bon, pour les curieux, je vous les tiens à disposition…

    Du coup, je me suis lancé dans la recherche d’application un peu mieux. Au bout de quelques heures de recherche, quelques applications téléchargées et installées, je m’aperçois que tous les onduleurs ont un protocole de communication totalement différent. Les logiciels d’un constructeur ne fonctionnent qu’avec leur propre onduleur. Les applications sont d’ailleurs toutes très variées, seules les versions pro proposent du SNMP et quasi pas de soft qui permette d’avoir un état dans une page Web.

    Je me suis donc rabattu sur le service « Onduleur » de Windows (on le trouve dans « Gestion d’énergie » sauf sur les portables). Et là, pas mieux. Un service de base où mis à part si l’on possède un APC, il n’y a pas grand-chose. Visiblement n’importe quel onduleur possède des instructions minimums qui permettent de vérifier son état : sur secteur, sur batterie, batterie faible. Les possibilités sont très limitées : arrêter la machine et exécuter un programme. Point barre.

    Je suis donc parti sur l’écriture d’un programme en ligne de commande qui permette d’envoyer un mail en SMTP. Cela me permettra en cas de panne électrique d’être alerté par mail de la coupure de courant. Mieux que rien. Je me suis dit que ça allait me faire du bien, presque 2 ans et demi sans écrire une ligne de code. Ca va me dérouiller un peu.

    Côté outil, je pars donc sur Visual Basic Express 2005. Une solution parfaite pour m’y remettre. Parfaite car j’adore Visual Basic (je « parle » aussi C/C++,Java, Pascal, Fortran, C#, ADA et « baragouine un peu » en Eiffel, Python, PhP). Parfaite aussi pour les étudiants, les débutants et les passionnés : le produit est gratuit, permet de développer en .NET 2.0 et offre des possibilités de recherche super sympa (j’y reviendrais plus loin). Après 15 minutes de téléchargement (OK, j’ai une bonne ligne ADSL), l’installation se passe sans encombre. Je prends évidemment la librairie MSDN avec moi. Pas besoin de SQL Express pour mon besoin (pour l’instant). SQL Express est une base de données, basée sur SQL Server et gratuite. SQL Express est idéal pour les développements, les tests, une utilisation en production avec quelques utilisateurs simultanés.

    Evidemment, j’active mon Visual Basic Express 2005, qui permet d’avoir accès à de nombreux avantages :

    • Corbis Image Pack — Un assortiment de 250 images Corbis gratuites à inclure dans vos sites Web et vos applications
    • La suite IconBuffet Studio Edition Icon — Une collection de plus de 100 icônes IconBuffet.com, professionnelles et gratuites
    • Une variété de composants — Une sélection de composants à utiliser dans vos applications
    • Des livres électroniques et des articles — Des livres électroniques Microsoft Press complets ainsi que des articles intéressants pour les débutants, les amateurs, et les personnes essayant les outils de développement Microsoft pour la première fois.

    D’ailleurs en ce moment, il y a un jeu Activ'Express avec 20 lots à gagner chaque mois. Bref aucune excuse pour ne pas activer ses version de Visual Studio Express.

    Côté développement, je me dis que j’allais commencer par chercher dans l’aide. Toujours commencer par réfléchir avant de coder :-). D’ailleurs la bonne règle, c’est autant de temps à réfléchir qu’à coder. Un nouveau menu est présent « Communauté » et « Recherche dans les communautés ». A l’intérieur, on trouve des recherches sur des exemples. Je lance donc la recherche qui m’ouvre une nouvelle fenêtre, je tape « envoi mail smtp ». J’obtiens de nombreux résultats dont un très bien sur MSDN intitulé « Envoi de courrier, exemple » en ce qui concerne Microsoft et un autre très bien aussi sur le réseau Codes-Sources (superbement piloté par mon ami Nix) intitulé « VB.NET envoi de mail pas SMTP avec authentification ».

    Résultat : avec ces deux exemples, en moins de 10 minutes, j’avais fait mon programme. Très cool côté productivité, moins cool côté « me remettre à faire un peu de code ». Du coup, c’est là que me vient l’idée d’aller plus loin et de réécrire un logiciel qui permette de gérer mon onduleur ! Mon onduleur possède deux ports de communication : série et USB. Je me lance pour série, je connais bien…

    Cela me rappellera mon jeune temps de développeur. J’étais à l’époque étudiant à l’ENSAM (les Arts et Métiers). Je passais mon temps libre et mes vacances à travailler pour la société SAMx. Cet éditeur de logiciel est spécialisé dans les logiciels d’analyse scientifique. Leurs logiciels communiquent avec des microsondes et spectromètres électroniques. La plupart de ces appareils à l’époque ne communiquait qu’en port série et/ou parallèle. Je me souviens d’un développement où l’objectif était de récupérer des données (des images représentant des cartographies) depuis des PDP vers des PC (à l’époque en 1996 sous Windows 95). C’était l’époque des premiers ports parallèle EPP et ECP. La technologie n’était tellement pas sèche qu’il m’a fallut développer un dongle spécifique pour réussir à fonctionner avec l’ensemble des chipsets disponibles sur le marché. J’ai appris à cette époque à vraiment me servir d’un oscilloscope… Au final, la solution fonctionnait parfaitement avec un port série sur lequel les informations de commande étaient envoyées et un port parallèle sur lequel les informations étaient reçues. Pour les autres développements, je n’avais que rarement accès aux matériels (une microsonde, cela prend une pièce complète, SAMx n’en possédait pas, nous allions chez des clients faire les test) et je devait donc d’une part bien développer en respectant les protocoles de communication (documentés dans des superbes docs comme celles des standards) et d’autre part bien émuler les tests ! C’est à cette époque que la VT100 est devenue une de mes meilleure amie.

    De là, j’ai gardé de très bons restes. Restes que j’ai appliqués à mon onduleur. Et vous comprendrez le titre de ce post au prochain post :-)

     

  • Laurent Ellerbach

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

    • 2 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

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

    • 1 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

    Creating and launching timer in .NET Microframework

    • 1 Comments

    In previous posts, I had the occasion to show how to implement a web server using HTTP and handling web request (in my example GET requests) with parameters URL like in a real Windows or Linux server running Internet Information Server (IIS) or Apache with a generated HTML page like for ASP.NET, PHP or Java. Of course in couple of Kilo bits of memory, you just can’t do the same as IIS or Apache. Of course, security is very limited, capacity to cache non existent and many functions does just not exist! But at least you can do what you want and you just can focus on creating web page by hands with real C# code using the standard HTML language Sourire for those of my age who have started to write web pages in 1993 or so remember that it’s not very complicated and notepad was your best friend. Youngest one using tools like Visual Studio, Eclipse or others just don’t know Clignement d'œil Ok, I’m probably a bit polemic there but they may be less comfortable doing it than people of my age or people who developed couple of ISAPI filters.

    So read first this post on the web server implementation, then how to setup the time and date, this one on how to generate a calendar then this one on how to create programs. All done? Good! now, we will create couple of timers to launch the sprinklers. the good news is that in .NET Microframework, there is all what you need to do that. the only thing you have to do is to add a line like that in your initialization phase. I’ve added it in the StartHttpServer function:

    Timer MyTimer = new Timer(new TimerCallback(ClockTimer_Tick), null, 30000, 30000);

    So we have created a Time object that will call a function ClockTimer_Tick every 30 seconds in 30 seconds. The ClockTimer_Tick function looks like:

    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?
        for (int i = 0; i < SprinklerPrograms.Count; i++)
        { 
            SprinklerProgram MySpr = (SprinklerProgram)SprinklerPrograms[i];
            if ((now.Year == MySpr.DateTimeStart.Year) && (now.Month == MySpr.DateTimeStart.Month) && (now.Day == MySpr.DateTimeStart.Day)
                && (now.Hour == MySpr.DateTimeStart.Hour) && (now.Minute >= MySpr.DateTimeStart.Minute))
            { // 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.
                Timer MyTime = new Timer(new TimerCallback(ClockStopSprinkler), null, (int)MySpr.Duration.Ticks/10000, 0);
                SprinklerPrograms.RemoveAt(i);
            }
        }
    }            
    

    It starts by creating a DateTime object that take the actual date time. It will be used to see if there are programs to launch. The loop just go thru all the programs. Programs are contained into an ArrayList SprinklerPrograms and contains objects that are SprinklerProgram. All this is describe in this post.

    So what it does is just testing if the program is the right year, right month, right day, right hour and if the minute to start is pasted. As the function is called every 30 seconds, a sprinkler will be started during the minute it was planned. To open the sprinkler, the Sprinkler function Open from the Sprinkler class is called. The code for the class looks like:

    static private OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
    public class Sprinkler
    {
        private bool MySpringlerisOpen = false;
        private int MySprinklerNumber;
        private bool MyManual = false;
    
        public Sprinkler(int SprNum)
        {
            MySprinklerNumber = SprNum;
            //need hardware here
        }
    
        // open or close a sprinkler
        public bool Open
        {
            get { return MySpringlerisOpen; }
            set
            {
                MySpringlerisOpen = value;
                //do harware here
                if (MySpringlerisOpen)
                    led.Write(true);
                else
                    led.Write(false);
            }
        }
        public bool Manual
        {   get { return MyManual; }
            set { MyManual = value; }
        }
            
    
        //read only property
        public int SprinklerNumber
        {
            get { return MySprinklerNumber; }
        }
    }

    This class does not include the real hardware work. It just light on the embedded led when a sprinkler is open and switch it of when closed. As there are multiple sprinklers sharing the same internal led, the led object as to be declare as a static object in the main class to be kept alive and shared by all the sprinklers.

    Here come the specific of the netduino. The internal led is an OutputPort and use a specific port. It can be found in the definition of the enum:

    public const Cpu.Pin ONBOARD_LED = 55;

    The sprinkler class contains the number of the sprinkler, if it is open and if it is a manual open or an automatic opening. The only way to create a sprinkler class is to give it a number. It is done as behind there will be some hardware initialization and all objects will need to be unique. When I’ll have done the hardware work, I’ll come back to post the necessary code Clignement d'œil

    So back to the launch of the program, the code will set the opening to manual and open it in the sprinkler:

    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.
    Timer MyTime = new Timer(new TimerCallback(ClockStopSprinkler), null, (int)MySpr.Duration.Ticks/10000, 0);
    SprinklerPrograms.RemoveAt(i);

    Then it will create a new timer that will be called after the duration specified to sprinkle. The Ticks member return a number of ticks. 10000 ticks represent 1 second. So the ClockStopSprinkler will be called after the right duration and only 1 time. The function is quite simple, it just reset all sprinklers to close. I’ve decided to do this as I feel it is much more secure. I just can’t run anyway 2 sprinklers at the same time as I don’t have enough water pressure to run more than once a time.

    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; 
        }
    }

    If the mode is manual, no reason to stop a sprinkler. The manual mode can be run in another page. I’ll describe this into a future post.

    So quite easy code here to open and close the sprinklers when needed. Just use simple timers! I hope you’ve also enjoyed this post. Coding makes you feel better Sourire and that’s just a marketing guy telling you this Clignement d'œil

  • Laurent Ellerbach

    Comment installer Visual Studio Express sur Vista RC1

    • 1 Comments

    Hier, j'ai fait le grand saut sur la toute dernière build 552 (la RC1 officielle de Vista). Il m'a fallu 2h30 pour sauvegarder les données et seulement une trentaine de minutes pour installer Vista… J'y ai ajouté Office 12 Beta technical refresh en français. Viens maintenant l'installation de Visual Basic Express (version gratuite, comme les autres de la gamme Visual Studio Express).

    J'ai suivi les recommandations d'être un simple utilisateur sur ma machine (seulement membre du groupe user). Ca a parfaitement été pour installer Office 12 (moyennant élévation de privilège sur demande automatique de Vista). Ca a également été pour quelques autres applications.

    Par contre, avec Visual Studio Express, ça ne fonctionne pas. Ca a l'air dû à un problème avec le BITS (le background internet transfer service) qui gère les téléchargements en tâche de fond. Du coup, aucun produit de la gamme Express ne s'installe. Une erreur au chargement des produits on line est renvoyée.

    Le contournement consiste donc à s'ajouter au groupe des administrateurs locaux (administrators en anglais ou administreurs en français), de se déloguer et de se reloguer (attention, pour que l'ajout au groupe prenne pleinement effet, il faut se déloguer et se reloguer).

    Ensuite, l'installation se passe sans histoire. Le produit fonctionne parfaitement bien. Il est ensuite possible de se retirer du groupe des administrateurs et le produit continue de parfaitement fonctionner. Attention, suivant le code que vous écrivez, les demandes d'élévation de privilèges vont être nombreuses. En même temps, c'est très bien pour apprendre à écrire du code qui nécessite un minimum de permission.

  • 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

    Display overlay images in HTML and javascript with .NET Microframework

    • 1 Comments

    In my current project of lighting my Lego city, I’m working on a simple web interface that will allow thru a HTTP web page to display an image and small lamp icons on overlay. In my previous project on automate my sprinklers, I’ve implemented a HTTP web server in my netduino. It’s working like any Apache or IIS with kind of dynamic pages like ASP, php or Java. of course the implementation is much smaller and do cover only the very basic functions like GET request and sending file over.

    So as for the sprinkler project, I started with the HTTP Server example provided in the .NET Microframework SDK. I’ve removed what I did not need (same as for the Sprinkler project) and added couple of features like conversion, GET parameter management. Now I have the base, I was looking at a way to display images on overlap. my HTML bases are quite old, last time I did a page by hand was for the sprinkler project but not really with images. So of course, I remember the <img> tag and the map attribute to create an image that can bi clicked in multiple areas but that was not really what I wanted. I wanted multiple real images to be displayed on top of each other and having the ability to click on them.

    I rapidly found the <span> tag which allow to display anything on anyplace on top of HTML code. So it was looking perfect for my usage. The way to use it is to create an area and place HTML code inside with a position on the page. As an example:

    <span style='position:
    absolute;margin-left:158px; margin-top:59px; width:55px;
    height:44px; top:20px; left:50px;'><a href="/"><img border=0 width=55 height=44
    src="lampoff.png"></a></span>
    

    This span will be positioned in an absolute position on the page, starting from 158 pixels from the left side of the page and 59 from the top. Then you have to add another 20 pixels from the top and 50 from the left. The size of this span will be 55 pixels width and 44 pixels height. And it will contain an <a> tag with an image. The size of the image is 55 pixels width and 44 pixels height. the question you may ask is why is the span control taking 2 parameters for each position? one called margin-left + left and for vertical positioning margin-top + top. So good question Sourire the idea there is to allow to position first the span based on a control on the page and then offer the possibility to add an offset. the top/left is the first positioning and the margin-top/margin-left the second one. You want a real example? OK, so lets go with my final page which looks like this:

    image

    As you can see, I’ve positioned some lamps on the main image. And on top of the image there is some text. Imagine than in my code, I want to add more text before, of change the font size. It will change the position of the main picture. So the position of the lamp icons will change too. If I hard code the position of those lamp icons with absolute numbers, I’ll have to change all of them if I do a modification on the page.

    Now, If I can get dynamically the position of the main image and then use the possibility to use the margin to adjust the position on the main image, the only thing I have to care of is really the position on the picture. Well, the bad news there is that in HTML there is no other way than doing javascript to get a position of an object. So I had to code in javascript, 2 functions. 1 which will give me the absolute top position of the image and one for the left position. I have to admit I did not write javascript for such a long time… And I also have to admit, it’s not a language I like very much. No strong typing, no real way to debug correctly, no real language structure and less productivity than with languages like C#, VB, Java, C/C++. But I did it, and here is the result:

    <script langague="Javascript">
            // function to return the absolute Top and Left position
            function findTop(iobj) { ttop = 0; while (iobj) 
    { ttop += iobj.offsetTop; iobj = iobj.offsetParent; }
    return ttop; } function findLeft(iobj) { tleft = 0; while (iobj)
    { tleft += iobj.offsetLeft; iobj = iobj.offsetParent; }
    return tleft; } //to use it if the id of your image is MyImage //findTop(document.all.MyImage); </script>

    The function findTop will take the object you want the top position in argument. In HTML you can have imbricated objects so you have to take care of this to get the real position of an object. So I did a very simple recursive loop to sum the top position of all the parents objects up to the point there won’t be any object. And I simply return the sum of those positions. I did the exact same function for the left position. Now question is: how to use it? well, that’s very simple Sourire Taking the previous example, it will be:

    <span style='position:
    absolute;margin-left:158px; margin-top:59px; width:55px;
    height:44px; top:findTop(document.all.MyImage); 
    left:findLeft(document.all.MyImage);'><a href="/">
    <
    img border=0 width=55 height=44 src="lampoff.png"></a></span>

    So rather than have a number after the left and top attributes, I just call the functions. It assume that the name of the picture is MyImage. To give a name to an object, just use the id attribute:

    <img alt="Map of the city" id=MyImage src="ville.jpg" />
    

    and that’s it! the overall code for the page I generate automatically looks like:

    <HTML><BODY>netduino Lego City
    <p>HTTP Method: GET<br>
    Requested URL: "/default.aspx?id=0;lg=True<br>
    HTTP Version: 1.1"<p>
    <
    script langague="Javascript"> // You don't need to worry about this function findTop(iobj) { ttop = 0; while (iobj)
    { ttop += iobj.offsetTop; iobj = iobj.offsetParent; }
    return ttop; } function findLeft(iobj) { tleft = 0; while (iobj)
    { tleft += iobj.offsetLeft; iobj = iobj.offsetParent; }
    return tleft; } </script> <p> Click the lamp to switch on or off </p><span style='position:absolute;margin-left:158;
    margin-top:59;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>
    <
    a href='/default.aspx?id=0;lg=False'>
    <
    img border=0 width=26 height=45 src="/WINFS/lampon.png"></a></span>
    <
    span style='position:absolute;margin-left:208;
    margin-top:300;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>
    <
    a href='/default.aspx?id=1;lg=True'>
    <
    img border=0 width=26 height=45 src="/WINFS/lampoff.png"></a></span>
    <
    span style='position:absolute;margin-left:10;
    margin-top:10;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>
    <
    a href='/default.aspx?id=2;lg=True'>
    <
    img border=0 width=26 height=45 src="/WINFS/lampoff.png"></a></span>
    <
    span style='position:absolute;margin-left:700;
    margin-top:550;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>
    <
    a href='/default.aspx?id=3;lg=True'>
    <
    img border=0 width=26 height=45 src="/WINFS/lampoff.png"></a></span>
    <
    img alt="" src="/WINFS/ville.jpg" /></p></BODY></HTML>

    The /WINFS/ path is due to the fact I was running this sample thru the emulator. If you run it on the netduino board, then the SD path is /SD/.

    So I have created all what I need to display an image, put some other pictures as overlap, have the possibility to click on them. Now the next step is about generating dynamically this page from the netduino which I did and I will post explanations in a next post. Of course, there is the possibility to do all this with CSS. It’s working exactly the same way. My need is very simple so I won’t use CSS there but maybe to make my page very sexy in the future. Enjoy this code and post written in a plane Rire

  • Laurent Ellerbach

    Creating dynamically a web page using .NET Micro framework

    • 0 Comments

    In a previous post, I’ve explain how to read a file using .NET Microframework, how to create a setup file and load it (and write it also), how to implement a web server using HTTP and managing dynamically web pages and parameters. This post will explain how to generate dynamically a page using files and code. So more or less the same idea but using all components this time.

    And the project is about lighting my Lego city. The idea is to be able to click on an image and a led will switch on or off in the Lego city. I’ll show in this post how to generate dynamically using files and code the page containing the overlay images from this post.

    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++)
        {
            //on cherche le paramètre strMonth
            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);
            }
        }

    This first part of the code is very similar to what I’ve explained in this post. The page parameters are analyzed, they are converted into real values. Here, each light has an id and a status. They can be on or off. Again, more information in some of my previous posts here.

    // if the ID value is valid, just light up the light :-)
    if ((iID != -1) && (iID < myLegoLight.Count))
    {
        ((LegoLight)myLegoLight[iID]).Light = bLight;
    }

    As it’s a web page and anyone can access it, there are a minimum of integrity to do Sourire I just check if the id is in the limit and load the object. More information on the LegoLight class here.

    string strResp = "<HTML><BODY>netduino Lego City<p>";
    
    // Print requested verb, URL and version.. Adds information from the request.
    strResp += "HTTP Method: " + request.HttpMethod + "<br> Requested URL: \"" + request.RawUrl +
        "<br> HTTP Version: " + request.ProtocolVersion + "\"<p>";
    strResp = OutPutStream(response, strResp);
    //send first part of the HTML File
    SendFile(response, strDefaultDir + "\\page1.ht");

    I create a string with the first part of the HTML page and for debug purpose, I add couple of information and send the string to the response object. Again, everything is explained there.

    The SendFile function is the one described in the post explaining how to read a file. Details here. strDefaultDir contains the directory where the file page1.ht is located. In the emulator it’s WINFS and in the netduino it’s SD. I change it “manually” depending on the environment I’m in. No real need to write code for this. Remember we are running an embedded application, no one will change it!! So things like this one can be written in the marble Sourire

    Page1.ht contains the following:

    <script langague="Javascript">
      // You don't need to worry about this
      function findTop(iobj) { ttop = 0; while (iobj) 
    { ttop += iobj.offsetTop; iobj = iobj.offsetParent; } return ttop; } function findLeft(iobj) { tleft = 0; while (iobj)
    { tleft += iobj.offsetLeft; iobj = iobj.offsetParent; } return tleft; } //This is all you need: //findTop(doucment.all.MyImage); </script> <p> Click the lamp to switch on or off </p>

    As expected, it’s just HTML code Sourire and if you want to understand what is the javascript in the page doing, read this post. By the way, I don’t like javascript, I truly prefer C/C++, C#, VB or even real Java (I say I prefer Java over javascript but it’s far far away from the 3 others Sourire).

    //build array of Span
    LegoLight mLegoLight;
    for (int i = 0; i < myLegoLight.Count; i++)
    {
        mLegoLight = (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 + ParamStart+ MyParamPage.id +
    ParamEqual + i + ParamSeparator + MyParamPage.lg + ParamEqual + !mLegoLight.Light + "'>"; strResp = OutPutStream(response, strResp); if (mLegoLight.Light) SendFile(response, strDefaultDir + "\\imgon.ht"); else SendFile(response, strDefaultDir + "\\imgoff.ht"); strResp += "</a></span>"; strResp = OutPutStream(response, strResp); }

    The next part of the code displays as a span over the main image all LegoLight object and depending if the state of the light is on or off send a different file. in one case it’s imgon.ht and in the other imgoff.ht. Both code are very similar:

    <img border=0 width=26 height=45 src="/WINFS/lampon.png">
    <img border=0 width=26 height=45 src="/WINFS/lampoff.png">

    Of course the /WINFS here reference the emulator path. In the reality it will be /SD as content will be in an SD card in the real word.

    And to finish, couple of lines:

    //send rest of the file
    SendFile(response, strDefaultDir + "\\page2.ht");
    
    strResp += "</BODY></HTML>";
    strResp = OutPutStream(response, strResp);

    They basically send the rest of the page. page2.ht just contains the image:

    <img alt="" src="/WINFS/ville.jpg" /></p>
    

    Again, here I’m using the emulator. In order to make it work, /WINFS need to be change to /SD to work on the Netduino.

    And you are done, here is a simple example that mix file and dynamic generated code to produce a web page in .NET Microframework Sourire Enjoy the beauty of the code Sourire

  • Laurent Ellerbach

    Dynamically watermark a picture in a ASP.NET page

    • 0 Comments

    In a previous post, I’ve explain how to use generic ASP.NET handlers to display a picture. The concept is easy to use and perfect to manipulate any kind of document you want to output in your web server. There equivalent of this in technologies like PHP or Java but it’s so easy to do using ASP.NET. In my previous post, I’ve used VB, so I’ll continue with VB Sourire Don’t worry, it’s as easy to do in C#!

    The overall code to watermark an image dynamically using the generic handler and the minimum manipulation code is here:

    <%@ WebHandler Language="VB" Class="Image" %>
    
    Imports System
    Imports System.Web
    Imports System.Net
    Imports System.IO
    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Drawing.Drawing2D
    
    Public Class Image : Implements IHttpHandler
        
        Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
            context.Response.ContentType = "image/jpeg"
            context.Response.AddHeader("Cache-Control", "private,must-revalidate,post-check=1,pre-check=2,no-cache")
                    
            Dim instanceHTTP As New WebClient
            Dim MaCamera As New Camera
            Dim MyUri As New Uri("file://c:/Temp/image.jpg")
            Dim returnValue As Stream
            
            Try
                
                returnValue = instanceHTTP.OpenRead(MyUri)
                
                Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)
                
                Dim MyText As String = Now.ToString("yyy-MM-dd HH-mm")
                Dim MyGraphics As Graphics = Graphics.FromImage(MyImage)
                Dim MyFont As Font = New Font(FontFamily.GenericSerif, 12)
                MyGraphics.DrawString(MyText, MyFont, Brushes.White, 100, 100)
                            
                MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
                MyGraphics.Dispose()
                MyImage.Dispose()
                
            Catch ex As Exception
                context.Response.Write("Error")
            End Try
            
        End Sub
     
        Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property
    
    End Class
    

    I will not explain again what I’ve explain in the previous post on the way handlers are working. So I’ll just concentrate on the image manipulation and how to write text in an image dynamically.

    returnValue = instanceHTTP.OpenRead(MyUri)
    
    Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)
    
    Dim MyText As String = Now.ToString("yyy-MM-dd HH-mm")
    Dim MyGraphics As Graphics = Graphics.FromImage(MyImage)
    Dim MyFont As Font = New Font(FontFamily.GenericSerif, 12)
    MyGraphics.DrawString(MyText, MyFont, Brushes.White, 100, 100)
                
    MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
    MyGraphics.Dispose()
    MyImage.Dispose()

    I first open a URI which contains an image. In my case a static image sitting on the hard drive but the idea here is to take it from a webcam for example. The URI is open as a stream and passed to an Image object.

    The idea here is to watermark the image with the date. So I create a simple string containing the date and time in a dedicated formatting. I like this formatting "yyy-MM-dd HH-mm" as it’s easy to sort especially with files. It does return a text like “2011-11-24 10-47”.

    Then I create a graphics object pointing on the image. This object is directly link to the image we have loaded and any modification made on the graphics object will impact the image. It’s the basic concept of pointers used here.

    In order to write text, you’ll have to choose a font. Again, nothing complicated here, choose your preferred font and the size. A good Serif and a 12 size will be enough in my example.

    And let the magic work using the DrawString method to draw in the graphics, so in the image your text. The 100 and 100 params are the X and Y starting point where to write the text. It starts on the upper left corner of the image. You can also use predefined points. But for the example, I keep it very simple.

    And as explain in the previous post, you just have to save your watermarked picture into the output stream and you’re done. Or almost done, don’t forget to dispose the graphics objects, better to do it especially if you want to scale up. The garbage collector will thank you Sourire

    Final result will look like that:

    image

    And of course, you can do more, much more using this handler. You can add shapes, transform the color schemas, apply filters, etc. .NET is full or very efficient graphics manipulations. so just use them! In my case I use it to tag pictures with date and time as in this example but also to control when I can access an image on some webcam. I do not expose them directly to the web. They are only accessible thru handlers like this. And only to specific persons (with a login and password) and on specific time. Maybe more in a next example!

    As always, feedback welcome Sourire The code and blog post written in a plane from Paris to Zagreb Sourire

  • Laurent Ellerbach

    J’ai hacké mon onduleur ou le reverse engineering de protocoles de communication (part 2)

    • 6 Comments

    Cette fois-ci, je vais rentrer plus dans le concret des quelques étapes clés à suivre pour déchiffrer le fonctionnement d’un protocole de communication. Pour ceux qui veulent suivre la genèse de l’article, allez voir le premier post.

    Je vais commencer par rappeler quelques principes de base quand on veut faire du reverse engineering. Loin de moi l’idée d’être exhaustif et de proposer une méthode infaillible et universelle. Ils sont juste basés sur le bon sens et des grands principes d’ingénierie. J’appliquerais ces principes sur mon exemple d’onduleur.

    La première étape consiste à se munir des bons outils : la documentation complète du vecteur d’information, des outils d’écoutes, des outils d’analyse et des outils de simulation. Pour un port série, c’est assez simple. C’est un des premiers ports à être apparu sur les ordinateurs. De base, il ne nécessite que 3 fils de base: une masse, une ligne de donnée montante et une ligne de données descendante. Certains montages peuvent nécessités d’autres lignes qui permettaient notamment, au début, de faire du contrôle de données.

    Alors pour commencer, qu’est-ce que RS232 ? Et bien, c’est une norme de communication série que l’on trouve RS232 à l’EIA/TIA et qui est identique aux normes CCITT V.24/V.28, X.20bis/X.21bis et ISO IS2110. Des mots bien compliqués pour l’appeler familièrement un « port série ». De bonnes explications en anglais sur Wikipedia. Pourquoi série ? Et bien tout simplement parce que les données sont transmises en série, les unes après les autres sur une seule ligne. La différence avec un port parallèle, c’est que sur le port parallèle, il faut un fil par bit (en général), et les données d’un mot sont transmises toutes en même temps. Le principe du port série est d’ailleurs réutilisé sur les ports SATA (contrôleurs de disques dur nouvel génération) qui remplace les ports PATA qui eux transmettaient les informations en parallèle. Le port USB est également un très bon exemple d’utilisation de transmission en série des informations. Chaque technologie présente ses avantages et ses inconvénients. Je ne rentrerais pas dans le détail ici car j’ai besoin d’espionner à un niveau plus haut dans les couches OSI que sur la couche de transport en tant que tel.

    Le port série se présente sous la forme de prises DB25 (25 broches), DB9 (9 broches) ou RJ45 (8 broches). Les plus courants sont DB9 (on les trouve sur les PC actuels). Les DB25 ne sont plus utilisés depuis pas mal d’années et on évite les RJ45 pour ne pas les confondre avec les prises réseaux. Côté physique, les 3 seuls chiffres à retenir sur une DB9, ce sont 2, 3 et 5. 5 est la masse. La câblage de base consiste donc à relier 2 appareils en mettant directement les broches 2 et 3 en liaison (ou très rarement 2-2 et 3-3) et relier entre elles les broches 5. Dans mon cas, un câble série était livré, je n’ai pas eu besoin de me prendre la tête avec du câblage. Cependant, cela peut s’avérer utile d’avoir 2 câbles tout prêts, un droit et un croisé (appelé câble null modem) pour faire ce type de manipulation. Les autres broches peuvent avoir leur importance suivant ce que l’on cherche à faire. Mais elles ne sont pas obligatoires. Tous les câblages sont disponibles dans la doc de Windows 2000 par exemple.

    Côté communication, le port série fonctionne avec :

    • un débit données, exprimé en baud : (150), 300, (600), 1 200, 2 400, (3 600), 4 800, 9 600, 19 200, 28 400, 38 400, 57 600, 115 200, entre parenthèse les débits possibles mais plus utilisés ou rarement utilisés. Avec les nouveaux chpsets, il est possible d’obtenir une plage plus large notamment entre 28,4 et 57,6 K baud.
    • un nombre de bit par mot 7 ou 8,
    • une parité : None (aucune), Odd (paire), Even (Impaire), Mark (marquée)
    • 1 ou 2 bits de stop

    Les informations sont codées du bit de point faible vers le bit de poids fort suivi du bit de parité (si pas none) et du ou des bits de stop. A priori, rien n’interdit les transmissions simultanées. Dans ce cas, il faut être sûr que les broches ready to send et ready do receive sont bien reliées les unes avec les autres.

    Pour pouvoir correctement espionner ce qui circule sur le port série, la première difficulté consiste donc à trouver la bon paramétrage. Ce n’est pas si facile car les possibilités sont nombreuses. Dans mon cas, je ne possède pas la documentation du protocole de communication, impossible donc de connaître les bonnes informations. Et rien n’est écrit sur le matériel. Pas d’information disponible.

    J’ai la « chance » d’avoir un logiciel qui communique déjà avec mon onduleur. La seule chose que je vais donc avoir besoin de faire, c’est de l’espionner pour obtenir ces informations. L’avantage d’être à ce niveau là, c’est que c’est du logiciel. Et comme on dit, en logiciel tout est possible . Donc, je pars m’équiper d’un outil d’écoute. J’en connais un très bien : PortMon. Il provient de Sysinternals. Un site avec de nombreux outils tous indispensables au bon développeur et administrateur réseau. Sysinternals vient d’ailleurs d’être racheté par Microsoft il y a quelques semaines. Mark Russinovich et Bryce Cogswell ont toujours été pour moi des idoles et ils vont certainement le rester longtemps. Le fonctionnement de PortMon est parfaitement documenté sur le site.

    PortMon permet d’écouter ce qui se passe sur un port série ou un port parallèle. Je lance donc PortMon, je paramètre l’utilisation du port pour l’ordinateur local et utilise le port COM1. Je lance ensuite l’outil de monitoring de l’onduleur et j’écoute. Et vous savez quoi ? Et bien, on trouve plein de choses intéressantes… La suite au prochain post.

     

  • 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

    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 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

    Télécharger gratuitement et légalement des logiciels Microsoft pour les étudiants !!

    • 0 Comments

    Si vous êtes étudiants en France, alors vous pouvez avoir accès à de nombreux logiciels Microsoft gratuitement et en toute légalité !

    Que faire ? Tout simplement se connecter sur http://www.microsoft.com/france/msdn/abonnements/academic/etudiants/telechargementdirect.mspx

    Quels sont les logiciels disponibles ?

    Visual Studio 2005 Professionnal

    Développez vos applications Windows, web, mobiles ou basées sur Microsoft Office Plus d'informations

    Visio

    Clarifiez vos idées et donnez vie à vos concepts ! Plus d'informations

    MS Project

    L'outil idéal pour planifier et gérer vos projets ! Plus d'informations

    One Note

    Organisez et réutilisez vos notes quand vous voulez ! Plus d'informations

    SQL Server 2005

    Le logiciel d'analyse et de gestion des données. Plus d'informations

    InfoPath 2003

    Travaillez sur des formulaires riches et dynamiques ! Plus d'informations

    Virtual PC 2004

    Pour exécuter plusieurs systèmes d'exploitation sur un seul ordinateur. Plus d'informations

     

    A ne pas rater !

Page 1 of 5 (122 items) 12345