DotNET

mbed .NET RPC Library

Here you can find a library for interfacing .NET programs with mbed using RPC.

This could be used for:

  • Controlling actuators from and reading data into .NET programs - over
  1. Serial (RS232)
  2. USB
  3. Bluetooth over serial or USB (e.g. Prolific chip)
  4. ZigBee over serial
  5. HTTP (see: .NET mbedRPC Library with HTTP support below)
  6. etc...
  • Creating a GUI for mbed programs

All this work could be done because you folks and mbed members did a great job. I just ported the Java stuff to .NET in a very easy manner. Thanks to Michael and to all others.

.NET is potentially a great choice for interfacing to mbed over a network as it can be run over Communication Foundation and across many different platforms - e.g.: .NET Micro Framework 4.1 for Visual Studio 2010 Express and all others (Appache Licence - absolutely free to use and portable to ARM controllers and others!), Compact Framework, Standard Framework .NET 4.0, ASP.NET, etc.). This page shows how to use the library to create .NET applications using serial and (later) over HTTP. HTTP is not implemented till now in this BETA, but will be soon.

Information

To use the mbedRPC library your mbed needs to be running code which can receive and execute RPC commands. Information and examples of this, can be found on the Interfacing-Using-RPC page. Compile and run the program for the type of transport mechanism you wish to use.

The .NET mbedRPC Serial Library

Here is the mbedRPC .NET library as a Visual Studio 2010 Project zip file: mbedRPC.zip - (no HTTP support - only serial/HTTP support see article below...)

And here an example of how to use the .NET mbed library and some simple code required to get started and flash LED1 and LED2 - like Michaels Java sample. This will run as a .NET Windows application.

mbedRPC_HelloWorld_DotNET

using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using org.mbed.RPC;

namespace mbedRPC.Test
{
    public partial class mbedRCPTest : Form
    {
        DigitalOut led1;        // mbed DigitalOut RPC declaration -> LED1
        DigitalOut led2;        // mbed DigitalOut RPC declaration -> LED2
        mbed mbed;              // the embed itself

        public mbedRCPTest()
        {
            InitializeComponent();
        }

        private void mbedRCPTest_Load(object sender, EventArgs e)
        {
            Debug.Print("mbed RPC Hello World");

		    //Create an mbed object for communication over USB (serial)
		    mbed = new SerialRxTxRPC("COM10", 9600);
            //Or over serial: mbed = new SerialRPC("COM10", 9600);
		    //Or later:   mbed = new HTTPRPC("http://192.168.2.2")
		
		    //Create new Digital Outputs on the mbed
		    led1 = new DigitalOut(mbed, mbed.LED1);
		    led2 = new DigitalOut(mbed, mbed.LED2);
        }

        private void flash(int n)
        {
            try
            {
                for (int i = 0; i < n; i++)
                {
                    //Call the DigitalOut objects' methods 
                    led1.write(1);          // on
                    led2.write(0);          // off
                    Thread.Sleep(250);      
                    led1.write(0);          // off
                    led2.write(1);          // on
                    Thread.Sleep(250);
                }
                led2.write(0);        // reset last state - all leds are off now
            }
            catch (NullReferenceException ex)
            {
                Debug.Print("No Reference: " + ex.Message);
            }
        }

        private void btnFlash_Click(object sender, EventArgs e)
        {
            btnFlash.Enabled = false;
            btnExit.Enabled = false;
            btnFlash.Text = "Is Flashing";
            flash(10);
            btnFlash.Text = "Start Flash";
            btnExit.Enabled = true;
            btnFlash.Enabled = true;
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            try
            {
                mbed.delete();
                Debug.Print("Complete");
            }
            catch (NullReferenceException ex)
            {
               Debug.Print("No Reference: " + ex.Message);
            }
            this.Close();
        }
    }
}

Quote:

And here the corresponding UI

/media/uploads/Stanislaus/ui.gif

mbedRPC_HelloWorld_DotNET (mbedrpc.test.zip)

Information

If you want to make an RPC call which isn't wrapped by the classes we have provided then use:

String RPCresponse = mbed.RPC(<String ObjectName>,<String MethodName>,<String[] Arguments>);

The .NET mbedRPC Library with HTTP support

Sorry for not updating the HTTP stuff for such a long time. I was very busy at my job and without time to do this. Thanks a lot for waking me up - Tom - and thanks for your code. I'll post my code now, too. So you can decide which one to use. The mebd community is great and producing a lot of code we all can share. :)

Information

As mentioned above - to use the mbedRPC library your mbed needs to be running code which can receive and execute RPC commands. Information and examples of this, can be found on the Interfacing-Using-RPC page. Compile and run the program for the type of transport mechanism you wish to use.

Short description how to use the code

After compiling the RPC library (Interfacing-Using-RPC) for mbed and downloading the code onto mbed you first of all have to start a terminal programme with mbed standard debugging settings (9600, 8, N, 1). Than reset your mbed and you will see this:

/media/uploads/Stanislaus/teraterm.gif

After round about 5 seconds you'll see an IP address the router has assigned to the mbed. This IP has to be used in the sample code and mbed is doing this over DHCP automatically for you.

using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using org.mbed.RPC;

namespace mbedRPC.Test
{
    public partial class mbedRCPTest : Form
    {
        // the mebed RPC methods
        private DigitalOut  led1;           // mbed DigitalOut RPC declaration -> LED1
        private DigitalOut led2;            // mbed DigitalOut RPC declaration -> LED2
        private DigitalOut led3;            // mbed DigitalOut RPC declaration -> LED1
        private DigitalOut led4;            // mbed DigitalOut RPC declaration -> LED2
        private AnalogOut analogOut;
        private AnalogIn analogIn;
        private PwmOut pwmOut;

        // the mbed objects 
        private HTTPRPC mbedHTTP;
        private mbed mbed;                  // the embed itself

        public mbedRCPTest()
        {
            InitializeComponent();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            try
            {
                mbed.delete();
                Debug.Print("Complete");
            }
            catch (NullReferenceException ex)
            {
               Debug.Print("No Reference: " + ex.Message);
            }
            this.Close();
        }

        private void mbedRCPTest_Load(object sender, EventArgs e)
        {
            // !!!!!ATTENTION!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // Set your mbed WEB Server address here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // This is the address you'll get back in your terminal programme !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            String myMBEDAddress = "http://192.168.2.108";      // this is the address the router gave me back
            Debug.Print("mbed RPC Hello World");

            // but test if reachable first
            mbedHTTP = new HTTPRPC(myMBEDAddress);

            if (mbedHTTP.IsAlive == false)
            {
                // not reachable -> wrong ip address or not connected, etc.
                labelAnswer.Text = mbedHTTP.StatusMessage;
            }
            else
            {
                labelAnswer.Text = mbedHTTP.StatusMessage;

                //both ways are possible
                //Decide with is okay for you
                mbed = mbedHTTP.MBED;                       // I prefer this one!
                //or:
                //mbed = new HTTPRPC(myMBEDAddress);        
            }

            try
            {
                //declare in/outputs on the mbed
                led1 = new DigitalOut(mbed, mbed.LED1);
                led2 = new DigitalOut(mbed, mbed.LED2);
                led3 = new DigitalOut(mbed, mbed.LED3);
                led4 = new DigitalOut(mbed, mbed.LED4);
                analogOut = new AnalogOut(mbed, mbed.p18);
                analogIn = new AnalogIn(mbed, mbed.p19);
                pwmOut = new PwmOut(mbed, mbed.LED4);
            }
            catch (NullReferenceException ex)
            {
                Debug.Print("No Reference at loading test: " + ex.Message);
            }
            catch (Exception ex)
            {
                //something went wrong
                Debug.Print("Error at loading test: " + ex.Message);
            }
        }

        private void flash(int n)
        {
            try
            {
                for (int i = 0; i < n; i++)
                {
                    //Call the DigitalOut objects' methods 
                    led2.write(1);          // on
                    led3.write(0);          // off
                    Thread.Sleep(250);      
                    led2.write(0);          // off
                    led3.write(1);          // on
                    Thread.Sleep(250);
                }
                led3.write(0);
                led2.write(0);        // reset last state - all leds are off now
            }
            catch (NullReferenceException ex)
            {
                Debug.Print("No Reference: " + ex.Message);
            }
        }

        private void btnFlash_Click(object sender, EventArgs e)
        {
            btnFlash.Enabled = false;
            btnExit.Enabled = false;
            btnFlash.Text = "Is Flashing";
            flash(5);
            btnFlash.Text = "Flashing LED2+3";
            btnExit.Enabled = true;
            btnFlash.Enabled = true;
        }

        private void checkBoxLED1_CheckedChanged(object sender, EventArgs e)
        {
            if(led1 == null) return;

            if (checkBoxLED1.CheckState == CheckState.Checked)
                led1.write(1);
            else
                led1.write(0);
        }

        private void checkBoxLED2_CheckedChanged(object sender, EventArgs e)
        {
            if (led2 == null) return;

            if (checkBoxLED2.CheckState == CheckState.Checked)
                led2.write(1);
            else
                led2.write(0);
        }

        private void checkBoxLED3_CheckedChanged(object sender, EventArgs e)
        {
            if (led3 == null) return;

            if (checkBoxLED3.CheckState == CheckState.Checked)
                led3.write(1);
            else
                led3.write(0);
        }

        private void btnAnalog_Click(object sender, EventArgs e)
        {
            analogOut.write(0.75f);
            double outVal = analogOut.read();
            double inVal = analogIn.read();
        }

        private void trackBarAnalogOut_ValueChanged(object sender, EventArgs e)
        {
            float val = trackBarAnalogOut.Value;
            float valOut = val / 10.0f;
            analogOut.write(valOut);

            double inVal = analogIn.read() * 3.3f;
            textBoxVoltage.Text = String.Format("{0:0.000}", Math.Round(inVal, 3));
        }

        private void btnPWM_Click(object sender, EventArgs e)
        {
            try
            {
                for (float p = 0.0f; p < 0.6f; p += 0.1f)
                {
                    pwmOut.write(p);
                }
                for (float p = 0.7f; p >= 0.0f; p -= 0.1f)
                {
                    pwmOut.write(p);
                }
                pwmOut.write(0.0f);
            }
            catch (NullReferenceException ex)
            {
                Debug.Print("No Reference: " + ex.Message);
            }
        }

        private void timerRPC_Tick(object sender, EventArgs e)
        {
            if (mbedHTTP != null)
            {
                if (mbedHTTP.IsAlive)
                {
                    btnReset.Enabled = false;
                    labelAnswer.Text = mbedHTTP.StatusMessage;
                }
                else
                {
                    btnReset.Enabled = true;
                    labelAnswer.Text = mbedHTTP.StatusMessage;
                }
            }
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            //check connection, router or cable
            //reset the flag and try again
            mbedHTTP.IsAlive = true;
        }
    }
}

See the exclamation marks in the source code above in the mbedRCPTest_Load function. Here you have to fill in the IP you get back from the router - visible in the terminal window. After doing so you have to recompile or to start your test project. If everything went well you'll see this window:

/media/uploads/Stanislaus/testgui.gif

If you see success (encirceled) in the dialog box, everything went well and you can use RPC over HTTP. If you don't have access to the mbed the Reset button is enabled and you can try to connect again after you have fixed your problem by ticking Reset button. If the problem is fixed success will be shown and the Reset button is disabled.

Here you can find the mbedRPC .NET library as a Visual Studio 2010 Project zip file: mbedRPCWithHTTP.zip

In the zip file you will find 2 paths:

  • mbedRPC -> the library with HTTP support now.
  • mbedRPC.Test -> the test programme with the common solution file.

Open the solution and both projects will be opened together and you can set the Test project as default and start it. But adapt the IP first!

More to improve in the future

The Library is synchronous for the moment - means the (.NET) client software has to wait for the mbed till it ends with the execution. Asynchronous methods should improve this. So the client software need not to wait till the mbed exectued the RPC commands. This is a fire and forget mechanism. The response is send than - after the mbed execution - in an event and should make the client software more fluent.

HTTPS is an issue, too. I have written the Library code to deal with credentials, but I never tested it. Plenty of things still to do. :)

Thanks to all and for your great support.