Laurent Ellerbach

Internet of Things, IoT, Arduino, Netduino, Galileo, Spark.IO, NETMF, .NET Microframework and other embedded gadgets :-)

  • Laurent Ellerbach

    Create a DHT11 C library using WiringPI on RaspberryPI and use it in Mono C#

    • 0 Comments

    I’m using various boards like RaspberryPI (1 and 2) as well as Arduino and Netduino. I have to say I’m a big fan of C#, so I try to use C# as much as I can. Based on the excellent WiringPI framework, I’ve ported equivalent of .NET Microframework classes to RaspberryPI (see previous post here, code not fully updated with latest Wiring PI version, just need to find some time to update it). All is using Mono on Linux.

    But as .NET is a managed code runtime, there are some limitations when it come to do some very short timing operations as managed code can’t guaranty those easily. In order to have those operations working, you’ll need to build some native C code. But wait, I know you’re a fan of C# like me and you don’t want to build your full project in C! It’s like the old time when we had the excellent Visual Basic to build all the graphical interfaces, fast development for anything related to interfaces but lack of performance. At this time, most of the code were don in a C/C++ dll and imported with the famous dllimport into the VB code.

    Well, we will do exactly the same here but replacing the old VB by the modern C# and for anything that need to be hard real time, we’ll put that into a C dll and import it into C#. But wait, here, our RaspberryPI is running Linux. So how to make that possible? In Linux as well, there are equivalent of dll, those are called library. They start with lib and have .so extensions. They are the exact same as dll but in the Linux world with the same advantages and same weaknesses.

    Then, let start by the library first. I wanted to find some code that already worked with the WiringPI framework as I’m using it (see this article on how to install it on a RaspberryPI). And I fond this great example which was almost what I wanted. I just needed to adapt it a bit to make it working.

    So I created (using my preferred tool Visual Studio), a normal C++ project. My main idea is to use it as an editor. I need 2 files: the library header and the core code. Both are important, and if you want to build a library you must have both. Let start with the header (called DHT11library.h in my code), here is the code:

    #ifndef _DHTLIB

    #define _DHTLIB

     

    #ifdef __cplusplus

    extern "C" {

    #endif

           extern bool InitDHT(int pinval);

           extern float getTemp();

           extern float getHumidity();

           extern bool dht11_read_val();

    #ifdef __cplusplus

    }

    #endif

     

    #endif

     

    What is the most important here is to have the entry point of the library properly declared in this header with extern. Now, the rest of the code in the file DHT11library.cpp:

    #include <wiringPi.h> 

    #include <stdio.h>

    #include <stdlib.h>

    #include <stdint.h>

    #include "DHT11library.h"

    #define MAX_TIME 85

    int DHT11PIN;

    int dht11_val[5] = { 0, 0, 0, 0, 0 };

    bool isinit = false;

     

    bool InitDHT(int pinval)

    {

           if (wiringPiSetup() == -1)

           {

                  isinit = false;

                  return isinit;

           }

           DHT11PIN = pinval;

           // initialize pin

     

           isinit = true;

           return isinit;

    }

     

    float getTemp()

    {

           return (float)(dht11_val[2] + dht11_val[3] / 10);

    }

     

    float getHumidity()

    {

           return (float)(dht11_val[0] + dht11_val[1] / 10);

    }

     

    bool dht11_read_val()

    {

           if (!isinit)

                  return false;

           uint8_t lststate = HIGH;

           uint8_t counter = 0;

           uint8_t j = 0, i;

           float farenheit;

           for (i = 0; i < 5; i++)

                  dht11_val[i] = 0;

           pinMode(DHT11PIN, OUTPUT);

           digitalWrite(DHT11PIN, LOW);

           delay(18);

           digitalWrite(DHT11PIN, HIGH);

           delayMicroseconds(40);

           pinMode(DHT11PIN, INPUT);

           for (i = 0; i < MAX_TIME; i++)

           {

                  counter = 0;

                  while (digitalRead(DHT11PIN) == lststate){

                         counter++;

                         delayMicroseconds(1);

                         if (counter == 255)

                               break;

                  }

                  lststate = digitalRead(DHT11PIN);

                  if (counter == 255)

                         break;

                  // top 3 transistions are ignored 

                  if ((i >= 4) && (i % 2 == 0)){

                         dht11_val[j / 8] <<= 1;

                         if (counter>16)

                               dht11_val[j / 8] |= 1;

                         j++;

                  }

           }

           // verify cheksum and print the verified data 

           if ((j >= 40) && (dht11_val[4] == ((dht11_val[0] + dht11_val[1] + dht11_val[2] + dht11_val[3]) & 0xFF)))

           {

                  if ((dht11_val[0] == 0) && (dht11_val[2] == 0))

                         return false;

                  return true;

           }

           return false;

    }

    As you can see, the code is very similar to the example code I found. I just added 3 functions to initialize the pin I’ll use and return both the temperature and humidity. Every time I’ll need to read the DHT11, I’ll call the dht11_read_val and then call both functions to return the temperature and humidity.

    Now, this is where you have to pay attention to make sure you’ll build the library correctly. You need to copy both file the DHT11library.cpp and .h into the Raspberry (I’m using a Samba share for this), then using PyuTTY or another way, connect to the Raspberry, go to the directory where you have placed the 2 files and compile the library:

    sudo gcc -o libDHT11.so DHT11library.cpp -L/usr/local/lib -lwiringPi –shared

    -o command will allow you to define the name of the library, on Linux, name need to start with lib and finish with so. At least that’s the only way I managed to make it working. I’m not a Linux expect so I may have miss something.

    -L and –lwinringPI reference the rest of the library. You must have compiled and installed the WiringPI framework before of course.

    -shared is the command to tell gcc to build a library

    If everything goes well, you’ll get your libDHT11.so compiled and ready to use. So let move to C# now. You can create a normal C# project using Visual Studio, .NET 4.0 type is recommended to work on Mono.

    I have created a class that embedded the C library and then allow to be used like a normal class:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Runtime.InteropServices;

    using System.Text;

    using RaspberryPiNETMF;

    using Microsoft.SPOT.Hardware;

    using System.Timers;

     

    namespace SerreManagement

    {

        public class NewDataArgs

        {

            public NewDataArgs(float temp, float hum)

            { Temperature = temp; Humidity = hum; }

            public float Temperature { get; private set; }

            public float Humidity { get; private set; }

        }

     

        class DHT11

        {

            //bool InitDHT(int pinval)

            [DllImport("libDHT11.so", EntryPoint = "InitDHT")]

            static extern bool InitDHT(int pinval);

            //float getTemp()

            [DllImport("libDHT11.so", EntryPoint = "getTemp")]

            static extern float getTemp();

            //float getHumidity()

            [DllImport("libDHT11.so", EntryPoint = "getHumidity")]

            static extern float getHumidity();

            //bool dht11_read_val()

            [DllImport("libDHT11.so", EntryPoint = "dht11_read_val")]

            static extern bool dht11_read_val();

     

            // private values

            private Cpu.Pin mPin;

            private int mSec;

            private Timer mTimer = new Timer();

     

            public delegate void NewData(object sender, NewDataArgs e);

            public event NewData EventNewData;

     

            // to get temperature and humidity

            public float Temperature { get; internal set; }

            public float Humidity { get; internal set; }

     

            public DHT11(Cpu.Pin pin, int seconds = 0)

            {

                mPin = pin;

                mSec = seconds;

                if (!InitDHT((int)pin))

                    throw new Exception("Error initalizing DHT11");

                mTimer.Elapsed += mTimer_Elapsed;

            }

     

            void mTimer_Elapsed(object sender, ElapsedEventArgs e)

            {

                if (dht11_read_val())

                {

                    Temperature = getTemp();

                    Humidity = getHumidity();

                    if (EventNewData != null)

                        EventNewData(this, new NewDataArgs(Temperature, Humidity));

                }

            }

     

            public void Start()

            {

                if (mSec != 0)

                {

                    mTimer.Interval = mSec * 1000;

                    mTimer.Start();

                }

            }

     

            public void Stop()

            {

                mTimer.Stop();

            }

     

            public bool ReadDHT11()

            {

                return (dht11_read_val());

            }

     

        }

    }

    The way to import the library is simple, it’s like for a Windows dll, it’s just the name changing. Be very careful if you build more complex library because the type conversion as well as pointers conversion may not be strait forward, you’ll need to use marshaling:

    //bool InitDHT(int pinval)

    [DllImport("libDHT11.so", EntryPoint = "InitDHT")]

    static extern bool InitDHT(int pinval);

    This is working with any kind of already existing Linux library, the only thing you need is the header file with the definition in order to find the right entry points as well as the exact types used.

    Then usage of the class is really simple:

    DHT11 mDHT;

    mDHT = new DHT11(Cpu.Pin.Pin_P1_18, 30);

    mDHT.EventNewData += mDHT_EventNewData;

    mDHT.Start();

    void mDHT_EventNewData(object sender, NewDataArgs e)

    {

        Console.WriteLine("Temp: " + e.Temperature + ", Hum: " + e.Humidity);

    }

     

    In our case, the DHT11 is linked to the Pin 18 on a Raspberry and the call for temperature and humidity is done every 30 seconds. The event is raised and the data can be read. You can then create an exe with Visual Studio, and run it on the RPI. Don’t forget to copy all the dll you’ll need as well as the libDHT11.so one. It is a dll so it has to be present with the exe. If not present, you’ll get an exception

    Results looks like:

    Temp: 23, Hum: 34

    The DHT11 is very simple and the temperature and humidity is not precise, you don’t have anything after the decimal point. the DHT22 is much better, it’s very easy to adapt this code to it, the difference with DHT11 is very tinny.

     

     

     

  • Laurent Ellerbach

    Internet of Things: installing Mono/Linux and Windows Embedded on a BeagleBone Black board (BBB)

    • 2 Comments

    The BeagleBone Black, also called Beagle Bone Black or BBB is an interesting board. It’s an AM335x 1GHz ARM Cortex-A8 with 512M of DDR3, 4GB of flash and does have an HDMI, USB client and host interface. But what I prefer are the 2 times 46 pins to have tons of IO available. It does reduce a bit the number if you are using HDMI. But still, it’s an interesting board. On the not as good aspect the analogic entries are only 1.8V max and not protected (so you need to add a 1.8V Zener diode to protect all analogic entries.

    clip_image001

    The board does natively run Linux on it on the embedded Flash. And you can flash it with another Linux or even Windows Embedded see here.

    I’m a C# guy (ok, sometimes I do some C++ too) so I like anything running C#. And I always try to find a way to develop using C# on any board. Sometimes it’s possible like for the RaspberyPi first version, see my blog post here. C” with either the full Microsoft .Net framework or the open source Mono one is a great way to be super productive in terms of development. Even in the embedded world if you don’t need hard code real time. And in the case you need some, then switch to C++ and create your own dll which you’ll be able to use later with C# for the rest.

    In this article, I’ll explain how to install a new Linux compatible to install Mono as well as a Windows Embedded image.

     

    The Linux way

    I’m not a Linux guy and I have to admit, I had to spend quite a lot of time for this step. I realized not all SD cards were compatible and I had no real way to check this on Linux before really booting on the SD. So make sure you have recent SD card and looks like it will work fine.

    Step 1: find a version that is BBB compatible

    After researches using Bing, I found a link explaining almost everything. The project was about developing using Mono including classes to access the GPIO. You’ll find the full site here. So I learned I need to install on the board an armhf version of Linux. The one present is just arm and Mono does not work on it.

    So after spending time figuring out that some of my SD card were not compatible while booting but compatible for flashing under Linux, I’ve finally found one recent compatible one. And to make sure the image was correct, I went for the Windows way of flashing. So I’ve downloaded an img file from here. The BB-ubuntu-14.04.2-console-armhf-2015-02_19-2gb.img.xz is working perfectly. And as recommended, I used the Win32DiskImager to flash the image. Other equivalent tools are also working perfectly.

    Once flashed, put the SD card into the SD card reader, press the button which is up to the SD card, plug the power and release the button. This will make the BBB boot on the SD card. If none of the blue led is flashing, then you’ve most likely have the same issue as me with none compatible SD card. Try with another one! If it’s blinking, then everything should be all good.

    You can easily test but using PuTTY or equivalent to connect to the board using SSH on port 22 with the IP address the board will get. If you don’t know or if you are not sure, just plug the board with the USB cable on your PC, use the address 192.168.7.2 to connect.

    If everything goes correctly, you’ll be able to log with “ubuntu” as username and “temppwd” as the password.

    clip_image003

    At this point, you can go to the next step. If you don’t have this screen, it does mean you’ve most likely miss something or your SD is not compatible.

    Step 2: installation Mono

    As explained in the RaspberyyPi first version article, steps are the same. Conect with PuTTY or equivalent, make sure this time, you’re plug to a network cable and have internet access.

    sudo apt-get update

    The password is the same as for the login so “temppwd”. Now, you are downloading all updates, it can take few minutes.

    sudo apt-get install mono-runtime

    this will get the mono runtime and will allow you to further develop using Visual Studio and C#. Careful as this image is just a console one. If you want to add a desktop, you need to install one. You can for example install Gnome like this:

    sudo apt-get install ubuntu-desktop

    Step 3: accessing the GPIO thru C#

    That’s where the first project I found is super useful as it’s a great, efficient implementation of OutpuPort and other well know classes from .Net Microrfamework (NETMF). You can download it directly from here. From this point, you can extract the source and directly use them in your project.

    You’re now ready to do a C# development using the BBB and some common NETMF classes J For the deployment, either copy your build, or use a network deployment or anything equivalent. I may write as well how to setup the debugger and environment to include a full debugger.

     

    The Windows Embedded way

    Step 1: prepare an SD Card with Windows Embedded

    Download the Windows image from Codeplex here. The download contains an example image.

    You’ll need to prepare your SD card. For this, use diskpart with an admin command prompt:

    clip_image005

    Then find your SD card, it should be easy to find with the size. Here it’s a 8Gb one, so it’s the Disk 2. Select it by typing

    Select disk 2

    You can then list the partitions with “List part” make sure there is just one partition, if it’s not the case, you may have done a mistake with your disk. If you are not sure, it’s better to exit the tool, format your SD card with Windows the normal way and make sure you just have one partition. Make sure the original partition is formatted in FAT32 or exFAT.

    Then select the particition with

    Select part 1

    Now the partition is selected, you need to make it active. This will allow the boot loader on the board to find the SD card and boot from there. This is done by using the command

    active

    clip_image007

    Exit from diskpart now. Now you need to copy the Windows Embedded files to the bootable SD card you’ve prepared. Launch the TI SDCard boot utility from the tools directory from the downloaded files. Select the MLO file. It will be copied first on the SDCard, then select the other elements so the EBOOTSD.nb0, the logo.bmp and NK.bin files.

    clip_image008

    Click proceed, skip the formatting of the SD card (should have been done previously and the partition is now active). One done, you’re ready!

    clip_image009

    Place the SD card in the SD card reader on the board, press the button which is up the SD card reader, plug the power and release the button.

    If everything went correctly, you are now running Windows Embedded Compact version on the BeagleBone Black.

    You can test by trying to find your board on the network. I’m using Advanced IP Scanner. If you’ve used the board previously, the IP address your DHCP server will give will be the same.

    clip_image010

    You can now access the board with Telnet or thru FTP. If you’ve done everything correctly, then you’ll be able to see this from the ftp address:

    clip_image012

    And from Telnet:

    clip_image014

    From here, you can now play a bit and try to connect remotely to the device with a tool called “Remote Display Control for Windows CE”. You’ll find the tool in the tools directory. Just type in the telnet session

    Cerdisp -c

    And launch the Host version on your desktop. You will see the board and you can now play with it.

    clip_image016

    Step 2: installing .NET and using GPIO

    OK, for this step, it’s a bit more complicated as it does require to rebuild totally a Windows CE image for this board. The platform elements are included in the BeagleBone WEC7 SDK file. Once you’ve installed the full Windows Embedded Compact 7, you then install the SDK. And you can create a project to include the .NET framework.

    I haven’t done it yet but I used Windows CE quite a long time ago and there is a lot of fun building your own OS with component. The god news is that Windows EC is free for individuals:

    Individual Non-Commercial Use. If you are an individual (that is, a natural person, and not an organization, business entity, or unit of government), then you may flash or download the Runtime Image to your device for your own Non-Commercial use.

    From full license here.

    Access to GPIO is then a bit of development as you’ll need to build a DLL to be able to do it or see if there is an existing one in the PAL.

    If you do an image, please let me know! Enjoy and have fun.

  • Laurent Ellerbach

    Servo motor tester in NETMF (.NET Micro Framework) with Netduino

    • 0 Comments

    I rencently bought new servo motor as I needed some to pilot new switches in my Lego train. The problem is I didn’t found the same as the previous one. Another problem is that I needed to replace one which didn’t worked properly.

    And here came the main issue: find the boundaries of those servo motors. There are databases online but my servo was not existing (or I didn’t found it). My new servo is a Motorcraft MC-410 sold by Connard. So I had to found the boundaries myself. Rather than testing fully blind, I’ve decided to make it in a flexible way. I have a Netduino Plus 2 available for my dev. I also developed a light WebServer. So why not build a simple webpage where I’ll be able to change the key settings of the servo and see the impact for real.

    In order to pilot correctly  servo motors, we need to use PWM. It’s quite straight forward to use for servo motors. It’s about having a period and a duration. This duration is from a minimum pulse to a maximum pulse. this will make move the servo motor from its base angle to its maximum angle.

    Usually servo are using a 20000 period and then the minimum pulse vary a lot around 800 microseconds and the maximum one around 2000, sometimes more. But it’s get quite complicated to find the right numbers especially because most of the time, the makers are not providing them as they are usually calibrated with a bit of analogic.

    I build a solution where I have a simple web page and I can change the settings of the servo motor and test them right away. The web page is super simple:

    image

    The way it’s working is quite simple, I start with some default settings, put the position at 50% and then try to change the min pulse to 700, then put 0 in the Position and see if it’s moving. If it’s moving, then the boundary is lower, if not, the boundary is higher. and the other way for the higher boundary. The period is usually 20K but some may be lower or higher. This allow also to test up to which value the servo still operate.

    And as a bonus, when the lower and higher boundaries are found, it does allow to measure the full angle the servo can give. In my case, close to 200° which does correspond to the spec.

    On the hardware side, it’s super simple, I’m using the pin D5 for the pilot cable to the servo, it’s a PWM on the Netduino. And then I use 5V and ground for the two other pins. The middle one in most servo is the +5V, the brown/black is the ground, the other one (can be yellow, white, orange, etc) is then the pilot one.

    Here is how it does looks like on my Lego test switch.

    WP_20150109_002

    In terms of software, I’m using my micro Web Server which I’ve developed. I’m using it because it’s light and I don’t need anything complicated. You can find the source code here and more explanation here.

    The full code source is here:

    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 NetduinoLibrary.Toolbox;

     

    namespace Servo_test

    {

        public class Program

        {

     

            static private SecretLabs.NETMF.Hardware.PWM pwm = new SecretLabs.NETMF.Hardware.PWM(Pins.GPIO_PIN_D5);

            private static WebServer server;

     

            //string constant

            private const string strOK = "OK";

            private const string strProblem = "Problem";

            private const string pageReq = "req.aspx";

            private const string paramMinPulse = "mi";

            private const string paramMaxPulse = "ma";

            private const string paramPeriod = "pe";

            private const string paramPosition = "po";

            //servo info

            static private uint MinPulse = 800;

            static private uint MaxPulse = 2200;

            static private uint Period = 20000;

            static private uint Position = 0;

     

            public static void Main()

            {

                server = new WebServer(80, 10000);

                server.CommandReceived += new WebServer.GetRequestHandler(ProcessClientGetRequest);

                server.Start();

                Thread.Sleep(Timeout.Infinite);

            }

     

            private static bool DecryptRequest(string strDecrypt)

            {

                // decode params

                WebServer.Param[] Params = WebServer.decryptParam(strDecrypt);

                int mMin = -1;

                int mMax = -1;

                int mPeriod = -1;

                int mPosition = -1;

                bool isvalid = true;

                if (Params != null)

                {

                    for (int i = 0; i < Params.Length; i++)

                    {

                        //on cherche le paramètre strMonth

                        int j = Params[i].Name.ToLower().IndexOf(paramMinPulse);

                        if (j == 0)

                        {

                            mMin = Convert.ToInt32(Params[i].Value);

                            if (mMin<0)

                                isvalid = false;

                        }

                        j = Params[i].Name.ToLower().IndexOf(paramMaxPulse);

                        if (j == 0)

                        {

                            mMax = Convert.ToInt32(Params[i].Value);

                            if (mMax<0)

                                isvalid = false;

     

                        }

                        j = Params[i].Name.ToLower().IndexOf(paramPeriod);

                        if (j == 0)

                        {

                            mPeriod = Convert.ToInt32(Params[i].Value);

                            if (mPeriod<0)

                                isvalid = false;

                        }

                        j = Params[i].Name.ToLower().IndexOf(paramPosition);

                        if (j == 0)

                        {

                            mPosition = Convert.ToInt32(Params[i].Value);

                            if (mPosition<0)

                                mPosition = 0;

                            if (mPosition > 100)

                                mPosition = 100;

                        }

                    }

                }

                // check if all params are correct

                if (isvalid)

                {

                    if (!Microsoft.SPOT.Hardware.SystemInfo.IsEmulator)

                    {

                        if(mMin > 0)

                        {

                            MinPulse = (uint)mMin;

                        }

                        if (mMax > 0)

                        {

                            MaxPulse = (uint)mMax;

                        }

                        if(mPeriod>0)

                        {

                            Period = (uint)mPeriod;

                        }

                        if(mPosition>=0)

                        {

                            Position = (uint)mPosition;

                        }

                        uint duration = (uint)(MinPulse + (MaxPulse - MinPulse)/100.0f*Position);                

                        //pwm.SetDutyCycle(duration);

                        pwm.SetPulse(Period, duration);

                    } 

                    else

                        Debug.Print("MinPulse " + mMin.ToString() + " MaxPulse " + mMax.ToString() + " Period " + mPeriod.ToString() + " Position " + mPosition.ToString());

                }

                else

                    isvalid = false;

     

                return isvalid;

            }

     

            private static void ProcessRequest(Socket response, string rawURL)

            {

                string strResp = "";

                if (DecryptRequest(rawURL))

                    strResp = strOK;

                else

                    strResp = strProblem;

                WebServer.OutPutStream(response, strResp);

            }

     

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

            {

                Socket response = e.response;

                string strResp = "";

                string strFilePath = e.rawURL;

     

                //HTP 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);

     

                if (strFilePath.Length >= pageReq.Length)

                {

                    if (strFilePath.Substring(0, pageReq.Length).ToLower() == pageReq)

                    {

                        ProcessRequest(response, strFilePath);

                        return;

                    }

                }

     

                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>Servo Motor Discover</title>";

                strResp += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/></head><body>";

                strResp += "<meta http-equiv=\"Cache-control\" content=\"no-cache\"/>";

                //create the script part

                strResp += "<script language=\"JavaScript\">var xhr = new XMLHttpRequest();function btnclicked(boxMSG, cmdSend) {";

                strResp += "document.getElementById('status').innerHTML=\"waiting\";";

                strResp += "xhr.open('GET', cmdSend + boxMSG.value);";

                strResp += "xhr.send(null); xhr.onreadystatechange = function() {if (xhr.readyState == 4) {document.getElementById('status').innerHTML=xhr.responseText;}};}";

                strResp += "</script>";

                strResp = WebServer.OutPutStream(response, strResp);

                //body

                strResp += "</head><body><table >";

                strResp += "<tr><td>Min pulse</td><td><input id=\"MinPulse\" type=\"text\" value=\""+MinPulse.ToString()+"\" /></td><td><input id=\"MinPulseBtn\" type=\"button\" value=\"Update\" onclick=\"btnclicked(document.getElementById('MinPulse'),'req.aspx?mi=')\"  /></td></tr>";

                strResp += "<tr><td>Max pulse</td><td><input id=\"MaxPulse\" type=\"text\" value=\""+MaxPulse.ToString()+"\" /></td><td><input id=\"MaxPulseBtn\" type=\"button\" value=\"Update\" onclick=\"btnclicked(document.getElementById('MaxPulse'),'req.aspx?ma=')\" /></td></tr>";

                strResp += "<tr><td>Period</td><td><input id=\"Period\" type=\"text\" value=\"" + Period.ToString() + "\" /></td><td><input id=\"PeriodBtn\" type=\"button\" value=\"Update\" onclick=\"btnclicked(document.getElementById('Period'),'req.aspx?pe=')\" /></td></tr>";

                strResp += "<tr><td>Position %</td><td><input id=\"Position\" type=\"text\" value=\"" + Position.ToString() + "\" /></td><td><input id=\"PositionBtn\" type=\"button\" value=\"Update\" onclick=\"btnclicked(document.getElementById('Position'),'req.aspx?po=')\" /></td></tr>";

                strResp += "</table><div id=\"status\"></div></body></html>";

                strResp = WebServer.OutPutStream(response, strResp);

            }

     

        }

    }

     

    The Main function just create the Web Server.

    ProcessClientGetRequest received all the Get requests from the Web Server. I do analyze the path. If the called page is “req.aspx” I do then call a sub function which will change the servo motor settings. If not, then the main page.

    Let start with the main page source code, I’m using background http requests to change the servo settings. This avoid reloading the page and make it light in terms of discussions with the board, only a light header is sent with a simple status. This is a very simple a typical script that all web dev knows.

    <script language="JavaScript">

    var xhr = new XMLHttpRequest();

    function btnclicked(boxMSG, cmdSend) {

    document.getElementById('status').innerHTML="waiting";

    xhr.open('GET', cmdSend + boxMSG.value);

    xhr.send(null);

    xhr.onreadystatechange = function() {

    if (xhr.readyState == 4) {

    document.getElementById('status').innerHTML=xhr.responseText;}};}

    </script>

     

    Then it’s a simple tables which does contains the various settings and a button which does call the req.aspx page to update the settings.

    <tr><td>Min pulse</td>

    <td><input id="MinPulse" type="text" value="800" /></td>

    <td><input id="MinPulseBtn" type="button" value="Update" onclick="btnclicked(document.getElementById('MinPulse'),'req.aspx?mi=')"  /></td></tr>

     

    I pass the object so in the code I can read the value. I can do it also in the call but this allow to do other modification if needed from the script. At the end, there is status div to pub the status sent back by the req.aspx page.

    The code to build the page has nothing complicated. The code of the page is build dynamically with predefined values for the text box.

    The function DecryptRequest decrypt the request and the settings. It’s rest API based with parameters in the URL. I would even be able to build a Windows Phone, Windows 8, Android or iOS App if I want Sourire Well, let say this test page is enough for me Rire

    In the function, after analyzing the parameters and validating few of them, in a very basic, it’s time to change the settings of the servo. The pulse is then calculated and the order to make the PWM work sent with the period.

    uint duration = (uint)(MinPulse + (MaxPulse - MinPulse)/100.0f*Position);                

    pwm.SetPulse(Period, duration);

     

    So all up, it’s a good reuse of my Web Server code. And good use of basic javascript in a page. It’s already something I’ve used in various projects and it’s really saving some time. So all up, it took me 5 minutes to find the right settings of the servo and will save me time in the future.

  • Laurent Ellerbach

    Manage my wine cellar with QR codes and Microsoft Azure

    • 1 Comments

    I have quite “few” bottles of wine. I really do like wine a lot. Yes, I’m French Sourire As for any resource you use a lot with lots of new items in and out almost every day, you start to have mistakes in your inventory. That’s what happen naturally to any inventory. And you need to rebuild it time to time to check if it’s still correct or not.

    For a very long time, I was using a simple Excel file to manage my wine cellar. With manually decreasing by handwriting the new number of bottles on each line. You can imagine how the line looks like when I have 12 bottles and drink them all between 2 inventory periods. Aalso adding new bottles manually on the paper was quite a challenge. So I needed to do the inventory at least 2 to 3 times a year.

    I was thinking of doing something with barcode and a simple barcode reader. Finally, I never took the time to do it. But recently, I got the idea of using QR Codes, smartphones to recognize the QR Codes and a Cloud website to store everything.

    I went naturally for Microsoft Azure for both the Website using ASP.NET + MVC + EntityFramework and a SQL Azure database. I would have been able to use PHP, Java or any web technology like this but my core skills are more on .NET and C# Sourire Note that for the usage I’m doing, the project hosting and database are fully free in Azure. So if you want to do the same, it will be fully free. So let see in 8 simple steps how to make this app.

    Step 1: Create the Azure Web Site from Visual Studio 2013

    Visual Studio 2013 is the best development tool I’ve ever used (yes, I do use to test, competitive ones, time to time). Visual Studio have multiple versions and some are for free like Visual Studio Community.

    You will need a Microsoft Azure subscription. To do this application, including the database, you won’t have to pay anything at all. The free hosting and free database is largely enough. So first, click on Trial on the Azure page and follow the steps. You'll have to use an existing Microsoft Account (ex Live ID), then you’ll have to put your credit card. This is for verification only, after the trial, you won’t be charged, you’ll be able to continue to use the free website and free database.

    To create an Azure Website, you can follow the step by step documented here. What is important is to keep the Authentication mechanism into the website, so to select “Individual User Accounts”. This is the only difference from the tutorial. I will use authentication in the web application to make sure not everyone can access some specific parts.

    image

    The project is now ready and you already have the ability to add new users. The AspNet* tables are used to manage the users and roles.

    image

    Every time a user is registered, the AspNetUsers is filled. As the basic pages does only contains email and password, those 2 are created. Note that the password is not stored, only the Hash code is for security reason. It’s a good habit not to share any password in a database but either a crypted one or just the hash.

    image

    Step 2: create the Wine database

    I made it super simple and straight forward: I’ve only created 1 table called “ListeVin” (WineList in English). Go to the Server management, select your Azure database and select manage it in the server explorer (you may get a message to update the firewall rules on Azure). Right click on Table from the database you’ve created with the website, select Add New Table.

    image

    You can then start creating new columns. In my case, I’ve created an Id which will be my primary key and can’t be null. Then a region, description and placement (“rangement”) which are text, a year (“annee”), quantity (“quantitee”) and years to keep (“Agarder”) which are integers. Yes, it’s simple, I should have add the creation date, the last update, another table to keep track of the modifications, etc. But I’m more interested for this version to just the necessary.

    image

    Once done, click on Update, and the database will the create.

    Step 3: create the Model associated to this table

    MVC means Model View Controller. The Model is the data part, the View is the page and the Controller is in the middle of the view and the data to perform advanced operations, manage some security, etc. So we need to add a Model first.

    On Models in your project, right click, select “Add” then “New Item…” and “ADO.NET Entity Data Model”.

    image

    Name it, then Add and select “EF Designer from database”.

    image

    If you haven’t setup the connection to the database, you’ll need to do it selecting “New Connection”

    image

    You can get the name of your database in the database properties or directly in the Azure portal. Select your database from the drop down list. The next step looks like this, you can include or not the login and password in the code or in the connection string. I’m adding it in the connection string.

    image

    In the next step, you select the table just created. Note you can select the other tables as well as views, store procedures and functions if you’ve created some.

    image

    Just click on Finish and you’ll get now your new entity created. The C# files has been created automatically and will make our life easier later on. There is no need to change anything to the generated code. You can have a look if you want to see all what you’ve avoided to do to access the database Sourire

    image

    Rebuild the full project. It’s important to make sure the Entity is recognize correctly.

    Step 4: Create the Controller and the View

    Right click on “Controllers” in the project, select “Controller…” and then “MVC 5 Controller with views, using Entity Framework” and click “Add”

    image

    Select the created Model in the previous step as well as the entity in the drop down list. Name it “ListeVinsController”, select “Generate views” at least and click “Add”. You can also select the layout of the project or do it later in the code of the pages.

    image

    You’re done for this step. It’s the moment to test the app! Hit F5. You’ll arrive on the default web page.

    Change the URL by replacing “/home/index” by “/ListeVins”. Please note that this name is the Controller name. It’s automatically done by default by removing the “Controller” part of the name. When we’ve created it, I’ve named it “ListeVinsController”. If you had names if “WineListController”, you’ll be able to access the page by putting “/WineList”.

    image

    At this moment, you can create new entries, edit then and delete them without any security. And you didn’t had to write any code either to have those pages! This is the beauty of those ASP.NET MVC default pages. And yes, of course, you’ll be able to modify the code later to adapt to your needs. I’ll show an example later.

    Step 5: Adding security

    As I wrote in the first step, few tables are created for the users. One is important, it’s called AspNetRoles. This is the one which contains the roles of users. The way the security is working in this MVC model is thru users and or roles. Users can be part of roles. I will use this notion of roles in the code.

    image

    I’ve create 2 roles in the previous table. I will use them later in the code. Be careful, they are case sensitive.

    The AspNetUsersRoles is the table linking a user with roles. I’ve linked a use to those 2 roles.

    image

    I do this manually but of course, yes, we can also build simple pages to manage all this. But I’ll have something like 5 users so I’ll do it directly in the database Sourire Please note that in development mode, you have also a local database. You have to do this modification as well in the local base to be able to use the roles and the users.

    The way to use this security in the code is working either by declaration either by code or both. I’ll use only the declarative way. And it’s very straight forward by adding [Authorize(Roles = “Admin”)] to give access to the admin roles. By default, all anonymous connections are allowed.

            // POST: ListeVins/Create

            // To protect from overposting attacks, please enable the specific properties you want to bind to, for

            // more details see http://go.microsoft.com/fwlink/?LinkId=317598.

            [HttpPost]

            [ValidateAntiForgeryToken]

            [Authorize(Roles="Admin")]

            public ActionResult Create([Bind(Include = "Id,Region,Description,Annee,Quantite,Rangement,Agarder")] ListeVin listeVin)

            {

                if (ModelState.IsValid)

                {

                    db.ListeVin.Add(listeVin);

                    db.SaveChanges();

                    return RedirectToAction("Index");

                }

     

                return View(listeVin);

            }

     

    You can define one or multiple roles, just separate them with a coma. You can do the same with users for example. But the notion of role is much more flexible than users.

            [Authorize(Roles = "Admin,CanEdit")]

            public ActionResult Edit(int? id)

            {

                if (id == null)

                {

                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

                }

                ListeVin listeVin = db.ListeVin.Find(id);

                if (listeVin == null)

                {

                    return HttpNotFound();

                }

                return View(listeVin);

            }

    I did it on the Create, Delete and Edit functions which are the key feature to protect.

    So if you are not registered or if you don’t have the right to access a specific part of the code, you’ll be redirected to the login page:

    image

    Once logged with the correct role, you can access to the Create page and create new set of bottles.

    image

    Step 6: Removing 1 bottle from the inventory

    I’ve create a specific function in the controller to decrease the number of bottles on a specific set of bottle.

            // GET: ListeVins/Decrease/5

            [Authorize(Roles = "CanEdit")]

            public ActionResult Decrease(int? id)

            {

                if (id == null)

                {

                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

                }

                ListeVin listeVin = db.ListeVin.Find(id);

                if (listeVin == null)

                {

                    return HttpNotFound();

                }

                listeVin.Quantite -= 1;

                db.SaveChanges();

                return RedirectToAction("Index");

            }

     

    The code is very similar to the delete one but I just decrease the quantity, save the changes and redirect on the full wine list. I don’t test anything, quantity can be negative. Again, this is very simple but largely enough for my needs. I should add a nice message sayaing everything has been updates, etc, etc. But hey, I’ll teach everyone at home. To call this function, I just have to go to“http://yoursite/listevins/decrease/1” to decrease by 1 the number or bottle of the bottle set numer 1 (replace yoursite by the url of your site).

    This is not very user friendly as none at home will remember what to call in the url, the id of a specific set of bottles. And that’s where QR Codes arrived Sourire

    Step 7: Adding QR codes with a redirect on the good URL

    I want everyone at home to be able to scan a RQ code sticked on a bottle with their Windows Phone (yea, it’s also working with other smartphones as well but everyone has Windows Phone at home Rire) and that’s it!

    But I’ll need to generate the QR Codes dynamically when I’ll create the set of bottles to be then able to print them and stick them on the bottles. Ho yes, this will take some time as I have quite a lot of bottles. But it’s the price to pay to make it simple on the other side. And once it’s done, it’s done! No need to change them even if I keep the bottles for 20 years or more Clignement d'œil

    I found a good QR Code project to generate QR Code on CodePlex: http://qrcodenet.codeplex.com/

    Once downloaded and referenced in the project. The usage is quite easy:

            public string GetQrCode(int? id)

            {

                return "<img src=\"/ListeVins/QrCode?id=" + id + "\" />";

            }

     

            public FileResult QRCode(int? id)

            {

                QrEncoder encoder = new QrEncoder(ErrorCorrectionLevel.M);

                QrCode qrCode;

                MemoryStream ms = new MemoryStream();

                encoder.TryEncode("https://yoursite/listevins/decrease/"+id, out qrCode);

     

     

                var render = new GraphicsRenderer(new FixedModuleSize(10, QuietZoneModules.Two));

                render.WriteToStream(qrCode.Matrix, ImageFormat.Png, ms);

                return File(ms.GetBuffer(), @"image/png"); ;

     

            }

     

    The GetQrCode function is just returning a simple string containing the call on the second function which does return a file, in our case an image. The image is generate dynamically by encoding the the URL. The image is generated in memory in a stream, the stream is saved as an image in the memory. In order to generate the right URL, change “yoursite” to the right URL.

    Now, I have to modify the “Details.cshtml” by adding this QR Code in the list, at the end. GetQrCode will be called, this will create the image tag. The image tab contains a call on the QRCode image creation and the image will be displayed.

    <dd>
        @Html.Action("GetQrCode", "ListeVins", new { id = Model.Id });
    </dd>

    image

    And as a result, the details page shows now the QR Code.

    image

    All what I need to do is copy/paste it in Word in a template that I’m using to print stickers, print them and stick them on the bottle!

    As you can also see, I’ve customized the main menu of the website as well as the footer. You can do all this by modifying the cshtml files from the home folder as well as the Shared one.

    Step 8: Scan and drink Sourire

    The last step is the user step. When anyone from the familly at home goes to the basement and take a bottle, he/she just have to scan the bottle using a QR Code app if they’re not using a Windows Phone or directly the visual search (Visual Bing) using a Windows Phone. And if they’ve installed Cortana, they can use QR for Cortana for example and launch the filter which does the QR Code recognition.

    wp_ss_20141226_0002

    The first time they scan a QR code, they just have to put their login and password in the website (like in Step 5), click “remind me” and they’re done for the other times. So very simple. And even if they forget to do it from the basement or they forgot their phone or whateverotherfakereasontheywillfind, I/they still can do it when they have the bottle upstairs.

    Now I can enjoy a great bottle of wine Sourire Feedback welcomes on the article as well on wine of course Sourire

  • Laurent Ellerbach

    Connect Arduino, Spark.IO, Netduino (NETMF .Net Microframework), to Microsoft Azure Mobile Services, create IoT (Part 3)

    • 2 Comments

    In the 2 previous articles, we’ve created a local network of objects which communicate sensor information to a more smarter object which will post the information somewhere in the Cloud. Idea is to create a full Internet of Things (IoT) infrastructure. Those sensors are temperature, humidity (air and soil), wind direction as well as rain. Some have been just reused from Oregon Scientific and some have been developed from scratch using simple Arduino or equivalent like Spark.IO.

    It is now time to look at how to post the sensor information in the Cloud. There are multiple offers to post data in the Cloud. I prefer the Microsoft Azure offer for multiple reasons. First, it’s free for a low usage like my hobbyist usage. Yes, it’s just free. Yes, really free. I will use for this the Azure Mobile Services as well as an Azure SQL database for the storage. The Azure SQL database is free up to 1Gb of data. And in one of the next article, we’ll see how to consume those data, also for free in an Azure Web site.

    There are also good technical reasons to use Azure: first it’s totally open, easy to access, based on the Internet protocols. All what you need is simply an IP stack and sockets. It can work on a low speed connection like GPRS or high speed like WiFi, using HTTPS or HTTP. So it’s very flexible and very easy to use. Let go deeper in the code. As a summary, Azure Mobile Services are:

    • Fully REST API, can be access HTTP or HTTPS, in our case, as the processors are very low end, it will be HTTP only
    • Dynamic table auto setup, no need to be SQL guru
    • Access thru application key, this is a simple but easy and simple security mechanism
    • Can customize insert, update and all other functions, I’ll use this to simplify a bit the data returned by Azure
    • Can create custom API, I’ll use this feature for the last part to connect my Sprinkler to the Azure data

    First step is to open an Azure subscription: http://azure.microsoft.com/pricing/free-trial/. Your credit card will be required but won’t be used if you decide to stay with free offer. The credit card is used for verification mainly. You’ll get 30 days also with real $$ to use for free if you want to test other part of Azure which I of course encourage you to do.

    First step is to create a Mobile Service. For this, just follow the excellent step by step you’ll find here. http://azure.microsoft.com/en-us/documentation/services/mobile-services/. It’s just 3 easy steps and you’re done for the server side.

    image

    Now the service is creates, to access it, it’s super simple: connect to the port 80 (stand HTTP port) of the Azure Mobile Service you’ve just created. And send the following data:

    POST /tables/weather/ HTTP/1.1

    X-ZUMO-APPLICATION: 123456789abcdef123456789abcdef12

    Host: nomduservice.azure-mobile.net

    Content-Length: 88

    Connection: close

    {"sensorID":22, "channel":5, "instSpeed":12,"averSpeed":5,"direction":2,"batterylife":90}

     

    The server will return the following text:

    HTTP/1.1 201 Created

    Cache-Control: no-cache

    Content-Length: 133

    Content-Type: application/json

    Location: https://nomduservice.azure-mobile.net/tables/weather//931CFDDE-AB7F-4480-BA28-F1D5C611398B

    Server: Microsoft-IIS/8.0

    x-zumo-version: Zumo.master.0.1.6.3803.Runtime

    X-Powered-By: ASP.NET

    Set-Cookie: ARRAffinity=da4a9f7437a690e3c1a799d3a6c3ddf3ee0cbb9f5a67008d3c919f0149f34ee3;Path=/;Domain= nomduservice.azure-mobile.net

    Date: Sun, 31 Aug 2014 15:40:12 GMT

    Connection: close

     

    {"sensorID":22,"channel":5,"instSpeed":12,"averSpeed":5,"direction":2,"batterylife":90,"id":"931CFDDE-AB7F-4480-BA28-F1D5C611398B"}

     

    yes, it’s HTTP, so it’s just simple text. What we send is a POST request on a specific table, here /tables/weather/ and we send information in a JSON format. See JSON as a simplified XML still readable by a human Sourire So basically a bit less text to send with still a structured way.

    What we get in return from the server is a standard header containing quite lots of information as well as the data and the unique ID returned. Wait, a unique ID? Yes, it’s part of what is generated automatically when you are using the Azure Mobile Services. All the database is created for you, all the mechanism to generate the data in the database is totally hidden for you. So clearly no need to be the king of SQL. It’s fully transparent. And yes, you can personalize, you can customize the received data, you can do check and all this. We'll have a look later on how to simply do it.

    OK, time to see code. Here is the full Arduino code necessary to post the example above:

    TCPClient client;

    byte AzureServer[] = { 12, 34, 56, 78 };

     

    String writeJsonWind(struct wind wd) {

      // Create a simple JSON;

      String datastring = "{\"sensorID\":";

      datastring += String(wd.ID);

      datastring += ",\"channel\":";

      datastring += String(wd.channel);

      datastring += ",\"instSpeed\":";

      datastring += String(wd.instantSpeed);

      datastring += ",\"averSpeed\":";

      datastring += String(wd.averageSpeed);

      datastring += ",\"direction\":";

      datastring += String(wd.direction);

      datastring += ",\"batterylife\":";

      datastring += String(wd.bat);

      datastring += "}";

      return (datastring);

    }

     

    void sendData(String thisData) {

      // create a connection to port 80 on the server

      // IP is your Mobile Services address

      if (client.connect(AzureServer, 80))

      {

      //Serial.println("Connected to Azure Server");

      // create the REST request using POST

      // Nomdelatable is name of the table

      client.print("POST /tables/weather/");

      client.println(" HTTP/1.1");

      // use the application key

      client.println("X-ZUMO-APPLICATION: 123456789abcdef123456789abcdef12");

      // host name is name of your Azure Mobile Service

      client.println("Host: nomdumobileservice.azure-mobile.net");

      client.print("Content-Length: ");

      client.println(thisData.length());

      client.println("Connection: close");

      client.println();

      // and finally data!

      client.println(thisData);

      }

      else {  // in case of error, stop connection

      client.stop();

      }  }

    // Sending data is simple, create a JSON, and send it on port 80!

    String dataString = writeJsonWind(myWind);

    sendData(dataString);

    That’s it? Yes, that’s it. Nothing more is needed. As I wrote before, you need an IP stack and sockets. You have them with the TCPClient object. I’m using a Spark.IO which is based on the same kind of processor you find in normal Arduino but with a WiFi chip on top. See previous articles for more information.

    Rest of the code is quite straight forward, the writeJsonWind function create the Json string. sendData is first connecting to the Azure Mobile Services server on port 80. Then a socket connection is created, it write in the socket the header and then the Json data. And that’s all! The data will be stored automatically in the SQL Azure database and you’ll be able to access them.

    It’s possible to personalize and create your own Azure Mobile Services API. You can do it either in Javascript directly in the Azure management console or in .NET using the excellent and free Visual Studio, either the Express version and installing the Azure SDK, either the Visual Studio Community edition. As an example, I’ll use Javascript here. The idea is to reduce number of data sent back to the client. No need to send the generated data, it won’t be use. The header will be largely enough.

    function insert(item, user, request) {

    request.execute({

    success: function(results) {

    request.respond(statusCodes.OK);  },

    error: function(results) {

    request.respond(statusCodes.BAD_REQUEST); }  }); }

    This is a simple modification which return OK if the data has been successfully entered into the database or bad request if not. You can of course do more. I encourage you to follow the project my friend Mario Vernari is doing here and here. Lots of great and cool stuff too with example of personalized API.

    As always, you can raise the question: what about security?

    It’s a critical part of Mobile Services. The default access is HTTPS which offers a reasonable level of security with the application key. Here, we are using very cheap processors which are not powerful enough to run HTTPS, so we are using basic HPPT. Of course, for a professional project or a project which require more sensible data, we’ll clearly have to use more robust processors. On top, you can use Azure Directory federation and make user/device authentication. When you’ll have to manage thousands of devices, when you’ll have them randomly in the wild and not physically secured, you’ll be happy to use those kind of mechanism to exclude specific devices. You have on top an easy federation with Microsoft ID, Google, Facebook and Twitter. And of course the Azure SQL database is secured with login/pwd, you can control which server/PC/device can have access by IP as well as user/pwd.

    What are the other way to post data in Azure? 

    There are other ways of course. You can access directly the SQL database but it’s not the easiest method to manage authentication, validate data. You better want to use the Azure Event Hubs to connect millions of devices across platforms and which allow the support for AMQP and HTTP. It does have native client libraries also exist for popular platforms

    You can also use framework like Intelligent Systems Service, more oriented to consume the data. It’s based on Azure, provide additional tools for analyze and data consumption.

    So all up, we’ve seen how to post data from a 1$ chip with access to an IP stack and Socket to Azure and store them in a SQL Azure database. It is simple, straight forward and flexible solution. It’s free for low usage so it makes it the best solution for simple projects and hobbyists.

  • Laurent Ellerbach

    Connect your Arduino, Spark.IO, Netduino (NETMF .Net Microframework), Galileo to Microsoft Azure (Part 2) to create an Internet of Things (IoT)

    • 0 Comments

    In the previous article, I’ve explained that I’ll build an Internet of Things (IoT) infrastructure to pilot automatically with sensors and a Microsoft Azure backend my Sprinkler system at home. I’ve also explained a bit the full architecture. In this post, I will explain how I have connected existing objects and make them communicating with the rest of the world as well as how I’ve created my own objects.

    I have decided to connect the existing Oregon Scientific sensors to the Cloud and Microsoft Azure Sourire In order to do that, without doing any modification on the existing sensors, I had to analyze how they’re build and how to be able to interface with them.

    image

    Those sensors are using a 433MHz band to communicate wireless to a base which can gather the information. Some are even connectable with a serial port. In my case, I didn’t had such a base. So I needed to basically decode the protocol and decrypt it. After a quick search on the internet, I found and excellent article from Olivier Lebrun in French (yes I’m French Sourire) here: http://connectingstuff.net/blog/decodage-protocole-oregon-arduino-1/. Olivier is using another article which is this time in English and which you can find here: http://jeelabs.net/projects/cafe/wiki/Decoding_the_Oregon_Scientific_V2_protocol

    The good news for me is that it’s easy and cheap to find a 433MHz demodulator and that the protocol used is simple and non crypted. In order to decode the protocol, I’ve decided to use an Arduino based processor. the reason is the very low cost and the fact that the existing code to decode is existing for Arduino. When searching a bit more, I found an Arduino compatible based processor which has an embedded wifi chip: Spark.IO. Good news is that it is still cheap and can be connected to the Internet. So with the Spark.IO, I can decode the protocol as well as posting information in Azure cloud.

    The wireless protocol use Manchester encoding. It’s a very common protocol used when doing wireless communications.

    image

    Source Wikipedia http://en.wikipedia.org/wiki/Manchester_encoding

    When a message is sent, it is transformed using the Manchester encoding and modulated at 433MHz. The graphic explains vey well how the information is sent. So in order to decode the signal, you can do it with the states changes and the timing between 2 changes. All this is very well explained in the 2 articles I4ve pointed.

    And as I can decode the protocol, I can also do the opposite and use a transmitter to send a signal. By doing this, I can have my own sensors. I’ll post an example of code later.

    The architecture I will use for my sensors and to connect them to Internet is a quite common one. It is used for years in alarms for example. Most sensors are only one direction, they use a close wireless protocol and send them information to a smart base. All what the open door detection sensor has to do is send time to time that he is alive and in case the door open send the signal it is open. It does not need to know if his signal has arrived or not and who did listen to him. And most sensors in the world are like that. But the smart base has to know all the sensors and has to monitor them. It has to make sure that they are all alive, or it will raise an alert. It aslo has to make sure that when the open door signal is raised it will also raise an alert. Today the only thing which is really connected to the internet and a another central point in an alarm system is the smart base.

    So I’ll use the same architecture for my project. Only the Spark.IO is connected to Internet thru its wifi. The other sensors are using the 433MHz wireless protocol to send their information. And they have no idea is it will arrive or not.

    image

    So the role of the Spark.IO is crucial. It will have the task to decode the messages send over the air as well as posting the information in Azure.

    The sensors I’ve developed are using ATmega 328 which is the processor used in the basic Arduino. it is very cheap, 1€, consume very low energy as well as possibility to sleep it to even more reduce the energy used. I wanted my sensors to be outside and fully autonomous. So I had to take case of this.

    Another great news is the possibility to use Visual Studio with the Visual Micro complement to develop for Arduino. Visual Studio Community Edition is free and have much more feature than the Arduino tools. Writing code is then super easy, it does support all the Ardunio flavor as well as a great debugger.

    imageimage

    Here is the example of the wind speed, wind direction and pluviometer. It is quite simple electronic. I bought the anemometer, wind vane and rain gauge sensors here. This was what cost me the most in the all project (70$)!

    image

    this is how it does look like as a prototype:

    clip_image002

    and integrated as a beta version fully autonomous in the garden

    WP_20141111_002

    inside the transparent box, there is Li-ion battery (3$), a Li-ion charger (2$) and a solar panel (6$) on top of what you have in the prototype picture.

     WP_20141111_004

    The power consumption is quite low, it can run in the dark on the battery for multiple days and few hours of a direct and intense sun is enough to fully recharge the battery.

    Here is a part of the code needed for the anemometer. It is quite straight forward:

    #define PIN_ANEMOMETER  2     // Digital 2

    #define PIN_ALIMRF   5      //Digital 5

     

    // How often we want to calculate wind speed or direction

    #define MSECS_CALC_WIND_SPEED 10

     

    volatile int numRevsAnemometer = 0; // Incremented in the interrupt

    ulong nextCalcSpeed;                // When we next calc the wind speed

    ulong time;                         // Millis() at each start of loop().

     

    // Buffer for Oregon message max size

    byte OregonMessageBuffer[12];

    byte numByteToSend = 12;

     

    Wind *myWind = new Wind();

     

    unsigned long lastSensorCheck = now();  

    const unsigned int interval = 5; // every 3 minutes = 3*60 sec

     

     

    void setup()

    {

           pinMode(PIN_ALIMRF, OUTPUT);

           pinMode(PIN_ANEMOMETER, INPUT);

           // set internal pull up

           digitalWrite(PIN_ANEMOMETER, HIGH);

           //set interuption

           attachInterrupt(0, countAnemometer, FALLING);

           nextCalcSpeed = now() + MSECS_CALC_WIND_SPEED;

           //other initis

    }

     

    void setWinMessage(){

           // Create the Oregon message for an Anemometer (WTGR800)

           byte ID[] = { 0x1A, 0x99 };

           setType(OregonMessageBuffer, ID);

           setChannel(OregonMessageBuffer, 0x20);

           setId(OregonMessageBuffer, 0x12);

           setBatteryLevel(OregonMessageBuffer, 1); // 0 : low, 1 : high

           setWind(OregonMessageBuffer, myWind->getInstantSpeed(), myWind->getAverageSpeed(), myWind->getDirection());

           byte numByteToSend = 10;

           csWind(OregonMessageBuffer);

           Serial.print("inst speed: ");

           Serial.print(myWind->getInstantSpeed());

           Serial.print(" aver speed: ");

           Serial.print(myWind->getAverageSpeed());

           Serial.print(" dir :");

           Serial.println(strVals[myWind->getDirection()]);

    }

     

     

    void sendMessage()

    {        // Show the Oregon Message

           digitalWrite(PIN_ALIMRF, HIGH);

           // wait 1 second that RF switch on

           delay(1000);

           for (byte i = 0; i < numByteToSend; ++i)   {

                  Serial.print(OregonMessageBuffer[i] >> 4, HEX);

                  Serial.print(OregonMessageBuffer[i] & 0x0F, HEX);

           }

           // Send the Message over RF

           sendOregon(OregonMessageBuffer, numByteToSend);

           // Send a "pause"

           SEND_LOW();

           delayMicroseconds(TWOTIME * 8);

           // Send a copie of the first message. The v2.1 protocol send the

           // message two time

           sendOregon(OregonMessageBuffer, numByteToSend);

     

           // Wait for 30 seconds before send a new message

           SEND_LOW();

           digitalWrite(PIN_ALIMRF, LOW);

    }

     

    void loop()

    {

           time = now();

     

           if (time >= nextCalcSpeed) {

                  calcWindSpeed();

                  setWinMessage();

                  sendMessage();

                  nextCalcSpeed = time + MSECS_CALC_WIND_SPEED;

           }

    // other treatment and other time related check

    }

     

    void countAnemometer() {

           numRevsAnemometer++;

    }

     

    And there are also functions used to send the message. Here, idea is to build few macros and then use them to send the low or high message:

    #define TX_PIN       4      //Digital 4

    const unsigned long TIME = 512;

    const unsigned long TWOTIME = TIME * 2;

     

    #define SEND_HIGH() digitalWrite(TX_PIN, HIGH)

    #define SEND_LOW() digitalWrite(TX_PIN, LOW)

    inline void sendZero(void)

    {

           SEND_HIGH();

           delayMicroseconds(TIME);

           SEND_LOW();

           delayMicroseconds(TWOTIME);

           SEND_HIGH();

           delayMicroseconds(TIME);

    }

    inline void sendOne(void)

    {

           SEND_LOW();

           delayMicroseconds(TIME);

           SEND_HIGH();

           delayMicroseconds(TWOTIME);

           SEND_LOW();

           delayMicroseconds(TIME);

    }

    inline void sendQuarterMSB(const byte data)

    {

           (bitRead(data, 4)) ? sendOne() : sendZero();

           (bitRead(data, 5)) ? sendOne() : sendZero();

           (bitRead(data, 6)) ? sendOne() : sendZero();

           (bitRead(data, 7)) ? sendOne() : sendZero();

    }

    inline void sendQuarterLSB(const byte data)

    {

           (bitRead(data, 0)) ? sendOne() : sendZero();

           (bitRead(data, 1)) ? sendOne() : sendZero();

           (bitRead(data, 2)) ? sendOne() : sendZero();

           (bitRead(data, 3)) ? sendOne() : sendZero();

    }

    It is quite straight forward to then send an information thru the 433MHz emitter. It’s just then about sending the bits one by one.

    I’m using a Spark.IO for the decoding part. The Spark.IO can be programmed over the air (OTA) and you need to use the development tools in a browser provided by the Spark.IO. The tools are ok to use, clearly much more limited than Visual Studio. It is still possible to use Visual Studio as for the Arduino but then you’ll need to be plugged in to program the chip. What I4m doing is I’m using Visual Studio for the code, the syntax and then copy/paste my code into the online editor to program the chip.

    It comes also with what they call a cloud. In reality, it’s just a server which provide access to information you can publish. But it is very limited and can’t be control in a smart way. So I will use Microsoft Azure instead. And I will explain it in the next part.

    Now on the Spark.IO, the way the decoding is working is this way:

    • First disconnect Spark.IO from it’s own server. If you don’t do it, you will never be able to decode correctly anything, the servers are taking lots of resources and interrupt the processes not in a needed time. So use Spark.disconnect(); in the main void setup() function. I am allowing e to reconnect it to make my life easier when I want to reprogram it over the air by using one of the entry. When I change the state of the entry, the server is reconnected so I can reprogram it over the air
    • A length is calculated between 2 state changes on the 433MHz receptor
    • if this length is between 200 and 700 milliseconds, then it’s a short, if it’s between 700 and 1200 it’s a long. Others are not valid and reinit the decoder
    • As soon as the impulsions are still valid:
      • The Manchester decoding is done for every new impulsion
      • The message is decoded on the flight
      • When the synchro is found (32 impulsions of 1 so 0xFF 0xFF received after the first 32 impulsions has been decoded), the sensor type is checked and what kind of data are expected.
      • if at some point data are not valid the decoder is reinitialyzed
    • When all the message is decoded, it is stored and it’s ready for the next one to be decoded

    This decoding part is well documented in the 2 articles I was referring before.

     

    This is how look like the Spark.IO with the receptor. The 433MHz demodulator is under the paper. In fact it’s a layer of paper plus few layers of aluminum and a layer of paper so like an aluminum sandwich. And the aluminum is then put to the ground. This simple method allow to isolate a bit the very cheap receptor I bought and increase drastically the decoding performances Sourire

    image

     

    There is a key question that can be raised here: the security one. In fact the data that are send by the sensors are not crypted and they are not secured. The initial temperature and humidity sensors are not protected. This is for a cost/sensibility reason. Those are not considered as sensitive. Of course, if you have to deal with sensitive data and send them with those kind of short range wireless protocols, do crypt them. This will increase of course the cost of your solution. But it’s the price to pay for security. And some of my neighbor is using also Oregon Scientific sensors and I can decode them and have access to them.

     

    So that’s it for this article. It did cover the sensor part, how to make existing sensor connected, how to create your own sensor, what kind of architecture to use and how to build a simple solution to decode everything. We will see next time how to post the data on Azure.

  • Laurent Ellerbach

    Connect your Arduino, Spark.IO, Netduino (.Net Microframework), Galileo to Microsoft Azure (Part 1)

    • 1 Comments

    Internet of Things (IoT) is exploding. Cost of processors and cost of electronic components is falling, electrical consumption is also getting lower and lower for more and more power. It’s now more than ever becoming to be super easy to create our own objects with some intelligence. Add to this technologies like Bluetooth Low Energy (BLE), some Wifi or GPRS low cost and low consumption, you can also add some connectivity, between each others and/or with Internet.

    What is the Internet of Things? “The network of physical objects that contain embedded technology to communicate and interact with their internal states or the external environment.” Gartner

    Being connected is nice but does not bring any value if the generate data are not used or if the object don’t take any action. For few years, the Cloud infrastructure like Microsoft Azure makes it easy to store and analyze those produced data or make it easy to consume data exposed by those infrastructures. So our objects can publish data in the Cloud as well as consume data that the Cloud host.

    IoT is more complex than most people thing about. And there as lots of questions that must be answered: create a brand new object or just add connectivity to an existing one? How to manage the object remotely? How to deploy new firmware to those new objects? How to secure access to those objects both physically as well as thru their communications and software? How to manage the generated data? How to analyze them? What to analyze? How to send back the data generated to some smartest objects? How to make an object adapt to data generated by others? What kind of hardware? What tools to use to develop on those new platforms?

    And those are just few examples of questions, there are many more that come in an IoT project.

    image

    To help answering those questions, we will separate the problem in multiple layers. Even if IoT is a fashion word those days, the full process behind and the way projects are managed is quite old and working for years. We will use the framework above in order to segment the problem. The first part will be related to the devices and objects we have. How to architecture them, why, how to connected them to the next layer which is the storage and cloud. We will then move to the data analytics, try to understand the data and get insights. With this, we will then go back the chain up to the objects themselves.

    In order to make it concrete, I will use a real example: my home and my sprinkler system.

    What I need: automate my sprinkler system based on elements like the temperature, the air and soil humidity, the sun light, the wind, the pluviometer.

    What I already have: I have my sprinkler system using .NET Microframework (NETMF), you’ll find previous article on how it is build in my blog here and here for example, you’ll find more in the full blog. This is already a big part of the system as it allows me to control manually and in a programmatically way my sprinkler. but it’s not fully automated based on external conditions. This sprinkler is based on Netduino Plus board using an ATMEL AT91SAM7X512 processor. NETMF is fully open source and as the name said, it’s mini .NET running directly on the metal without any OS. It can be develop with C# using Visual Studio.

    image

    I do also have existing Oregon Scientific sensors. My idea is to reuse them for the temperature and air humidity. I will make them communicating with the Internet. We will see how to do it in a next article.

    image

    What I’ve decided to do: I’ve decided to reuse the Oregon Scientific sensors, make them connected to the Internet. For this, I’ve decided to use Arduino and Spark.IO. Both are based on the cheap ATMEL ATmega328 processor. Both implement the open source Wiring.org framework. This framework is easy to use based on C/C++ and it does make easy to build simple devices. You’ll find tons of do it yourself (DIY) projects based on Arduino. I also wanted to show that it is super easy to connect those objects to Microsoft Azure Cloud infrastructure. Keep in mind that a simple ATMEL ATmega328 cost 1€. So it’s a very cheap solution. The good news with the Wiring.org framework is that it can also run on top of an OS like Linux or Windows. As an example, it’s the case for the Arduino YÚN or Galileo. Galileo boards can run Linux or Windows and have the Wiring.org layer on top. See http://dev.windows.com/en-us/featured/Windows-Developer-Program-for-IoT for more info as well as the sources https://github.com/ms-iot for the Windows version. The Windows version is free to run on those boards.

    Having an OS below those frameworks allow to have more security, capacity to encrypt data, do authentication and more. But at the same time, you are increasing the cost of your solution. We will discuss a bit the security further as it’s an important point. But it’s like in any project: it has a cost. So up to you to place the cursor where you think it must be. The more security you’ll need, the more costly it will be.

    So my final architecture will look like this:

    image

    I will have sensors, my Oregon Scientific existing sensors, new ones I will create using the same wireless 433MHHz protocol as the existing Oregon Scientific sensors. A Spark.IO will be decrypting the data and posting them on Microsoft Azure using the Azure Mobile Services. The data will be stored in a SQL Azure database. I’ve build a full Azure Website using ASP.NET + MVC + Entity Framework + jquery. And my Sprinkler will connect also to the Azure Mobile Services to consume the data produced and take decision to sprinkler or not.

    I will go step by step to describe the full architecture in the next parts. This was just the intro to explain the full architecture. Stay tune!

  • Laurent Ellerbach

    .NET Microframework on RaspberryPi (Part 2)

    • 1 Comments

    I realize I haven’t posted on my blog the direct link to the porting of .NET Microframework (NETMF) to the RaspberryPi. See previous article.

    So code is available here: https://raspberrypinetmf.codeplex.com/. This is not a full port of NETMF natively on RaspberryPi. It’s a port of specific NETMF classes on Mono running on Linux. It can be useful to quickly port existing NETMF projects with very little or no modifications. Note also that some classes are missing. So don’t hesitate to participate.

    Enjoy!

  • Laurent Ellerbach

    Building an Internet of Things garden with Arduino/Netduino/Azure

    • 0 Comments

    For those who follow this blog, it’s been a while I haven’t posted anything. Reason of time missing and also because I worked on a new project so documentation of the project was not the priority.

    But now it’s time to start the documentation and sharing. I gave recently a conference in Kiev to explain how the project is working and all the technologies involved.

    Presentation for the day as well as full presentation with more details can be found on my OneDrive here.

    So you’ll find in the coming months quite detailed article to explain how to publish information from an Arduino or any thing with an IP stack/Socket. Stay tune Sourire

  • Laurent Ellerbach

    .NET Microframework on RaspberryPi (Part 1)

    • 6 Comments

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

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

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

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

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

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

    sudo apt-get update

    sudo apt-get install xrdp

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

    sudo apt-get install mono-runtime

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

    sudo apt-get install git

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

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

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

    tar -zxvf bcm2835-1.25.tar.gz

    cd bcm2835-1.25

    ./configure

    make

    sudo make install

    cd src

    cc -shared bcm2835.o -o libbcm2835.so

    cd

    rm bcm2835-1.25.tar.gz

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

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

    image

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

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

    image

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

    Sudo mono yourprogramm.exe

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

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

     

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

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

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

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

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

    image

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

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

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

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

  • Laurent Ellerbach

    Ultrasound sensor and .NET Microframework (NETMF)

    • 0 Comments

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

    There are 4 pins:

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

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

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

    image

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

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

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

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

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

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

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

    Enjoy!

  • Laurent Ellerbach

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

    • 2 Comments

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

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

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

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

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

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

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

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

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

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

     

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

    image 

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

  • Laurent Ellerbach

    .NET Microframework (NETMF) Web Server source code available

    • 3 Comments

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

    It does include the following features:

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

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

    Feedback welcome!

  • Laurent Ellerbach

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

    • 2 Comments

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

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

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

    imageimage

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

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

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

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

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

     

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

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

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

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

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

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

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

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

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

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

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

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

    Now, lets have a look at the CSS file:

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

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

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

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

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

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

  • Laurent Ellerbach

    How software can solve hardware problems

    • 1 Comments

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

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

    image

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

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

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

    image

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

    image

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

    image

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

    image

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

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

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

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

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

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

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

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

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

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

  • Laurent Ellerbach

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

    • 2 Comments

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

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

    WP_000846

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

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

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

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

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

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

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

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

    Now let have a look at the timer

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

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

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

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

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

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

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

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

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

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

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

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

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

    The final result looks like this with 1 humidity sensor:

    image

    And the code to build the page is easy:

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

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

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

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

    image

    When updates, the result is the following:

    image

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

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

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

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

  • Laurent Ellerbach

    A low cost humidity sensor for my sprinkler system

    • 1 Comments

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

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

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

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

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

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

    image

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

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

    The code is extremely simple:

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

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

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

    I get the following results:

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

    And here is the picture of the prototype:

    WP_000792 

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

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

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

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

  • Laurent Ellerbach

    Using XMLHttpRequest to pilot a Lego train dynamically in HTML 5

    • 4 Comments

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

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

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

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

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

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

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

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

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

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

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

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

    The page with 4 trains looks like this:

    image

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

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

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

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

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

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

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

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

  • Laurent Ellerbach

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

    • 4 Comments

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

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

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

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

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

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

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

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

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

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

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

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

     

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

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

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

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

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

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

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

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

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

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

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

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

    Now, to use the server, easy:

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

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

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

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

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

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

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

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

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

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

  • Laurent Ellerbach

    Using a SPI device with netduino and .NET micro framework

    • 0 Comments

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

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

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

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

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

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

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

    image

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

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

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

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

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

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

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

     

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

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

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

  • Laurent Ellerbach

    Managing my Sprinklers from the Cloud

    • 1 Comments

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

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

    WP_000611

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

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

    WP_000612

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

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

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

    image

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

    Stay tune!

  • Laurent Ellerbach

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

    • 0 Comments

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

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

    The function is part of the LegoInfrared class and looks like

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

    LegoSpeed and LegoChannel are both enums.

    The simple view of the HTTPServer Class is the following:

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

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

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

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

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

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

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

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

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

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

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

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

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

    image

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

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

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

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

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

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

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

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

  • Laurent Ellerbach

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

    • 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