MEDC Berlin - Micro Framework Session Demo

Those of you at my MEDC session in Berlin would have seen me build a Micro Framework application, from scratch, that allowed you to visually set a desired temperature and then communicate this across an RS232 interface.

For the demo I used the Freescale Emulator and i.MXS board.  However it is possible to recreate the majority of the demo using just the i.MXS emulator, which is freely downloadable.

To recreate the demo you will need to have installed:

Instructions:

  1. Create a new Windows Application Micro Framework project.
  2. Replace/Amend Program.cs with the code below.
  3. Add the Freescale CPU.cs file from the Developer Kit Sample Project
  4. In the project properties, set the Transport as "Emulator" and the device as "i.MXS Emulator"
  5. Build & Run

If you are using real hardware, don't forget to set the Configuration Manager option to "deploy".

Please let me know if you have any questions

-Dave

--------------------------------

using System;

using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;

using System.Text;                              // UTF Encoding
using Microsoft.SPOT.Hardware;                  // Added - CPU.cs
using Microsoft.SPOT.Hardware.FreescaleMXSDemo; // Added - CPU.cs
using Microsoft.SPOT.Presentation.Media;        // Colour, etc

namespace MEDCDemo1
{
    public class Program : Microsoft.SPOT.Application
    {
        // Instantiate Resources & variables
        static Bitmap Canvas;                   // Bitmap Canvas
        static Font font = Resources.GetFont(Resources.FontResources.small);
        static SerialPort serialPort = null;    // Serial Communication

        static int temp = 18;                   // Default Temperature
        static int mintemp = 12;                // Minimum Temperature
        static int maxtemp = 24;                // Maximum Temperature
       
        public static void Main()
        {
            Program myApplication = new Program();

            Window mainWindow = myApplication.CreateWindow();

            // Initialise the drawing Canvas
            Canvas = new Bitmap(mainWindow.Width, mainWindow.Height);       // Bitmap holding the picture
           
            // Set up serial port
            SerialPort.Configuration serialConfig = new SerialPort.Configuration((SerialPort.Serial)0, (SerialPort.BaudRate)115200, false);
            serialPort = new SerialPort(serialConfig);
            Debug.Print("Serial port is writing/listening to " + serialPort.Config.Com + " at " + serialPort.Config.Speed);
       
            // Set up Up Button Interrupt - Up button is GPIO_PORT_B_11
            InterruptPort UpButton = new InterruptPort(Pins.GPIO_PORT_B_11, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            UpButton.OnInterrupt += new GPIOInterruptEventHandler(UpButtonPush);

            // Set up Down Button Interrupt - Down button is GPIO_PORT_B_10
            InterruptPort DownButton = new InterruptPort(Pins.GPIO_PORT_B_10, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            DownButton.OnInterrupt += new GPIOInterruptEventHandler(DownButtonPush);

            // Create the object that configures the GPIO pins to buttons.
            //GPIOButtonInputProvider inputProvider = new GPIOButtonInputProvider(null);

            // Start the application
            myApplication.Run(mainWindow);
        }

        private Window mainWindow;

        public Window CreateWindow()
        {
            // Create a window object and set its size to the
            // size of the display.
            mainWindow = new Window();
            mainWindow.Height = SystemMetrics.ScreenHeight;
            mainWindow.Width = SystemMetrics.ScreenWidth;

            // Create a single text control.
            //Text text = new Text();

            //text.Font = Resources.GetFont(Resources.FontResources.small);
            //text.TextContent = Resources.GetString(Resources.StringResources.String1);
            //text.HorizontalAlignment = Microsoft.SPOT.Presentation.HorizontalAlignment.Center;
            //text.VerticalAlignment = Microsoft.SPOT.Presentation.VerticalAlignment.Center;

            // Add the text control to the window.
            //mainWindow.Child = text;

            // Connect the button handler to all of the buttons.
            //mainWindow.AddHandler(Buttons.ButtonUpEvent, new ButtonEventHandler(OnButtonUp), false);

            // Set the window visibility to visible.
            mainWindow.Visibility = Visibility.Visible;

            // Attach the button focus to the window.
            Buttons.Focus(mainWindow);

            return mainWindow;
        }

        private void OnButtonUp(object sender, ButtonEventArgs e)
        {
            // Print the button code to the Visual Studio output window.
            Debug.Print(e.Button.ToString());
        }

        // //
        // Handle Up Button Push Event //
        // //
        public static void UpButtonPush(Cpu.Pin port, Boolean state, TimeSpan time)
        {
            if (state) // Only handle button down
            {
                Debug.Print("Up");

                if (temp < maxtemp)  // Ensure we don't go above max
                {
                    temp++;
                    Drawtemp(temp);
                    ChangeTemp(temp);
                }
            }
        }

        // //
        // Handle Down Button Push Event //
        // //
        public static void DownButtonPush(Cpu.Pin port, Boolean state, TimeSpan time)
        {
            if (state) // Only handle button down
            {
                Debug.Print("Down");

                if (temp > mintemp)  // Ensure we don't go below min
                {
                    temp--;
                    Drawtemp(temp);
                    ChangeTemp(temp);
                }
            }
        }

        // //
        // Helper - Draw Graphic Display //
        // //
        private static void Drawtemp(int temp)
        {
            // Calculate temperature interval
            int y = Canvas.Height - ((Canvas.Height / (maxtemp - mintemp)) * (temp - mintemp));

            // Draw white background
            Canvas.DrawRectangle(Color.White, 1, 0, 0, Canvas.Width, Canvas.Height, 0, 0, Color.White, 0, 0, Color.White, Canvas.Width, Canvas.Height, 256);
            // Draw Temperature Bar
            Canvas.DrawRectangle(Color.Black, 25, 0, y, Canvas.Width, 1, 0, 0, 0, 0, 0, 0, 0, 0, 256);
            // Add Temperature to Bar
            Canvas.DrawText(temp.ToString(), font, Color.White, 150, y - 5);
            //Display the temperature
            Canvas.Flush();
        }

        // //
        // Helper - Change Thermostat //
        // //
        private static void ChangeTemp(int temp)
        {
            // Ensure we have a serial port
            if (serialPort != null)
            {
                // Encode to UTF8
                UTF8Encoding enc = new UTF8Encoding();
                // Encode Byte array
                string tempString = "Temperature = " + temp.ToString() + "\r\n";
                byte[] tempData = enc.GetBytes(tempString);
                // Write to Serial Port
                serialPort.Write(tempData, 0, tempData.Length);

                Debug.Print(tempString);
            }
        }
    }
}

Comments

  • Anonymous
    July 04, 2007
    Hi Dave, I assisted to your past MEDC Session talking about .NET Micro Framework. Nice session! Really interesting! I tried to speak with you after the session but you were in a hurry and after that, I couldn't neither reach you in the bar area nor exchange with you a visit card. A pity.... Anyway, just wanted to tell you our particular case. People from my company are working with microdevices like Gumstix. I'm sure you know them. Very powerful devices (almost all of them running Linux), that offer many connection capabilities (Wifi, Bluetooth...) and at a very-very cheap price. Will microdevices running MicroFramework include such extended capabilities like Gumstix devices? The problem I see is that microdevices nowadays available running .NET MicroFramework seem pretty much simpler than Gumstix. Just and RS-232 interface and little more. I'd love to code for microdevices using C# and VS2005 but still don't see very advanced devices, in terms of capabilities, and prototypes are not very cheap. I would really appreciate if you could give me some more info regarding this issue. Other thing: you mentioned in the session that one possible application scenario were dataloggers. But also said that there is no a file system, so, where to store all logging info? I understand there is no database possibility in this environment. And how to send logged info to a remote machine? And last, but not least, what about the relation between domotics world and .NET Micro Framework? I saw at the keynote a video in which lights from a room were switched on/off. Would be possible to do these things with microdevices running .NET MicroFramework? As you see, I'm very newbie to this micro environment. My background has been always .NET Framework, Compact Framework and ASP.NET. Thanks very much in advance.

  • Anonymous
    July 08, 2007
    Many thanks for the feedback. I'm sorry that we did not get chance to meet-up after the session, we must vacate the room to allow the next session to set up which is why we move to the device bar afterwards.  I was on the stand for 2 hours after the session. The idea behind the .NET Micro Framework is that hardware OEMS can quickly and cheaply produce many different H/W configurations, i.e. everything from the Digi Connect ME board which is relatively cheap right up to the FreeScale and Embedded Fusion Tahoe boards.  It is planned to provide broader support for connectivity, however because you can build on a standard platform it is also possible to create your own hardware support. As mentioned above there are an increasing number of OEMs supplying many different derivations of Micro Framework boards at a large range of prices.  Embedded Fusion's website gives great details on both development kits and volume pricing for their Meridian CPU. Datalogging will generally involve sending the data directly from the device (e.g. using the Digi Connect ME board which has inbuilt TCP/IP) however you may want to cache onboard persisting the data by setting the Garbage Collection priority. The Micro Framework is designed for home automation scenarios.  Because of its small size, power requirements and connectivity it can be easily embedded into home appliances, and infrastructure. Hope this helps -Dave

  • Anonymous
    July 10, 2007
    Thanks for the sample code. I was able to make it run on my custom dotNETMF-enabled board by just changing 3 lines of code. Here is one of the many interests of managed code on embedded devices !!!

  • Anonymous
    July 10, 2007
    ...and which 3 lines did you have to change?  Button mappings and screen origin?

  • Anonymous
    July 10, 2007
    Button mappings and serial port configuration. It was just to see how easy it was to use the same code on two different platforms.