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

April, 2013

  • Laurent Ellerbach

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

    • 2 Comments

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

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

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

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

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

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

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

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

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

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

     

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

    image 

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

  • Laurent Ellerbach

    .NET Microframework (NETMF) Web Server source code available

    • 3 Comments

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

    It does include the following features:

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

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

    Feedback welcome!

  • Laurent Ellerbach

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

    • 2 Comments

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

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

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

    imageimage

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

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

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

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

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

     

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

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

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

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

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

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

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

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

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

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

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

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

    Now, lets have a look at the CSS file:

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

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

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

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

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

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

Page 1 of 1 (3 items)