.NET Gadgeteer Web Service Surveillance Camera

Here’s an example that uses the GHI Electronics Ethernet_J11D module to implement a surveillance camera that sends pictures to a Web browser.  Web Server functionality is part of the Gadgeteer.Networking class.

<This code updated on January 24, 2012, to use the new API >

The example uses the GHIElectronics modules shown in the following screen shot of the Visual Studio .NET Gadgeeteer Designer, including a Camera, a MulticolorLED, the  Ethernet_J11D module ,and a Button.  The designer illustration also shows the Fez Spider Mainboard.  The USB Client DP Module, DualPower, module (UsbClientDP) is not shown in designer diagrams.

Surveillance Camera Web Service Modules

Surveillance Camera Web Service Modules

The camera takes pictures and captures them in the basic .NET event model.  First set up the event to handle the event raised when the camera finishes taking a picture:

    camera.PictureCaptured +=
              new Camera.PictureCapturedEventHandler(camera_PictureCaptured);

The camera is activated by a Web Event in this Web service scenario.

        void webEventtakepicture_WebEventReceived(string path, WebServer.HttpMethod method, Responder responder)
        {
            if (button.IsLedOn)
            {
                camera.TakePicture();
                responder.Respond("Picture taken");
                return;
            }

            responder.Respond("Not taking pictures now");
        }

Setting up the Web event uses the WebServer.SetUpWebEvent method as shown in the following snippets. First initialize the Web event, and then assign a delegate to handle the event when it is raised by a request from the client, which can be any Web browser. The event handler to take a picture is shown in the previous code snippets.

     webEventtakepicture = WebServer.SetupWebEvent("takepicture");
     webEventtakepicture.WebEventReceived +=
          new WebEvent.ReceivedWebEventHandler(webEventtakepicture_WebEventReceived);

This example uses four Web events. Three of them are initialized in the Module.NetworkModule.NetworkUp event of the Ethernet_J11D module.

        void ethernet_NetworkUp(GTM.Module.NetworkModule sender,
                              GTM.Module.NetworkModule.NetworkState state)
        {
            Debug.Print("Connected to network.");
            Debug.Print("IP address: " + ethernet.NetworkSettings.IPAddress);
            WebServer.StartLocalServer("192.168.1.200", 80);

            webEventtakepicture = WebServer.SetupWebEvent("takepicture");
            webEventtakepicture.WebEventReceived += new WebEvent.ReceivedWebEventHandler(webEventtakepicture_WebEventReceived);

            webEventgetsinglepicture = WebServer.SetupWebEvent("getsinglepicture");
            webEventgetsinglepicture.WebEventReceived += new WebEvent.ReceivedWebEventHandler(webEventgetsinglepicture_WebEventReceived);

            webEventLed = WebServer.SetupWebEvent("led");
            webEventLed.WebEventReceived += new WebEvent.ReceivedWebEventHandler(webEventLed_WebEventReceived);

            led.TurnGreen();
        }

The fourth Web event is set up inside another Web event that determines the state of a LED module and toggles whether the Web service will send pictures repeatedly every two seconds.

        void webEventLed_WebEventReceived(string path, WebServer.HttpMethod method, Responder responder)
        {
            Debug.Print("path: " + path + method.ToString());

            if (responder.UrlParameters.Contains("ledstate"))
            {
                if (responder.UrlParameters["ledstate"].ToString() == "onmulti")
                {
                    led.BlinkRepeatedly(GT.Color.Orange);

                    webEventGetPicturesMulti =
                        WebServer.SetupWebEvent("getpicturesmulti", 2);  //Tell web browser to auto-refresh after 2 seconds

                    webEventGetPicturesMulti.WebEventReceived
                        += new WebEvent.ReceivedWebEventHandler(webEventGetPicturesMulti_WebEventReceived);

                    responder.Respond("<html>Multi state on; call <a href=\"http://192.168.1.200:80/getpicturesmulti\">http://192.168.1.200:80/getpicturesmulti</a> to get pictures every two seconds.</html>");
                }
                else if (responder.UrlParameters["ledstate"].ToString() == "offmulti")
                {
                    WebServer.DisableWebEvent(webEventGetPicturesMulti);
                    led.TurnGreen();
                    responder.Respond("Multi state off");
                }
            }
        }

From a Web browser the user sends Web GET requests in the following syntax to take, or get, a single picture or to set the Web service to respond with multiple images.  To stop the sequence of multiple images, call http://129.186.1.200/led?ledstate=offmulti.  The IP address of the Web service is listed in the Output in Visual Studio when the assemblies are loaded to the mainboard and the service starts.  Note that this sample is for a private network.  To make the IP addresses accessible on the Internet, you have to configure your router and DNS to support it.


//http://129.186.1.200/takepicture

//http://129.186.1.200/getsinglepicture

//http://129.186.1.200/led?ledstate=onmulti

//http://129.186.1.200/led?ledstate=offmulti

//http://129.186.1.200/getpicturesmulti

The flow of the application can be analyzed in the complete code listing that follows.

using Microsoft.SPOT;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace SurveillanceCamera
{
    public partial class Program
    {
        GT.Networking.WebEvent webEventLed;
        GT.Networking.WebEvent webEventtakepicture;
        GT.Networking.WebEvent webEventgetsinglepicture;
        GT.Networking.WebEvent webEventGetPicturesMulti;

        GT.Picture pictureForService;

        void ProgramStarted()
        {
            ethernet.UseDHCP();
            ethernet.NetworkUp +=
               new GTM.Module.NetworkModule.NetworkEventHandler(ethernet_NetworkUp);
            ethernet.NetworkDown += new GTM.Module.NetworkModule.NetworkEventHandler(ethernet_NetworkDown);
            button.ButtonReleased += new Button.ButtonEventHandler(button_ButtonReleased);
            camera.PictureCaptured += new Camera.PictureCapturedEventHandler(camera_PictureCaptured);

            led.TurnRed();
            // Do one-time tasks here
            Debug.Print("Program Started");
        }

        void camera_PictureCaptured(Camera sender, GT.Picture picture)
        {
            pictureForService = picture;
        }

        void button_ButtonReleased(Button sender, Button.ButtonState state)
        {
            button.ToggleLED();
        }

        void ethernet_NetworkUp(GTM.Module.NetworkModule sender,
                              GTM.Module.NetworkModule.NetworkState state)
        {
            Debug.Print("Connected to network.");
            Debug.Print("IP address: " + ethernet.NetworkSettings.IPAddress);
            WebServer.StartLocalServer("192.168.1.200", 80);

            webEventtakepicture = WebServer.SetupWebEvent("takepicture");
            webEventtakepicture.WebEventReceived += new WebEvent.ReceivedWebEventHandler(webEventtakepicture_WebEventReceived);

            webEventgetsinglepicture = WebServer.SetupWebEvent("getsinglepicture");
            webEventgetsinglepicture.WebEventReceived += new WebEvent.ReceivedWebEventHandler(webEventgetsinglepicture_WebEventReceived);

            webEventLed = WebServer.SetupWebEvent("led");
            webEventLed.WebEventReceived += new WebEvent.ReceivedWebEventHandler(webEventLed_WebEventReceived);

            led.TurnGreen();
        }

        void webEventgetsinglepicture_WebEventReceived(string path, WebServer.HttpMethod method, Responder responder)
        {
            if (pictureForService != null)
                responder.Respond(pictureForService);
        }

        void webEventtakepicture_WebEventReceived(string path, WebServer.HttpMethod method, Responder responder)
        {
            if (button.IsLedOn)
            {
                camera.TakePicture();
                responder.Respond("Picture taken");
                return;
            }

            responder.Respond("Not taking pictures now");
        }

        void ethernet_NetworkDown(GTM.Module.NetworkModule sender, GTM.Module.NetworkModule.NetworkState state)
        {
            led.TurnRed();
        }

        void webEventLed_WebEventReceived(string path, WebServer.HttpMethod method, Responder responder)
        {
            Debug.Print("path: " + path + method.ToString());

            if (responder.UrlParameters.Contains("ledstate"))
            {
                if (responder.UrlParameters["ledstate"].ToString() == "onmulti")
                {
                    led.BlinkRepeatedly(GT.Color.Orange);

                    webEventGetPicturesMulti =
                        WebServer.SetupWebEvent("getpicturesmulti", 2);  //Tell web browser to auto-refresh after 2 seconds

                    webEventGetPicturesMulti.WebEventReceived += new WebEvent.ReceivedWebEventHandler(webEventGetPicturesMulti_WebEventReceived);

                    responder.Respond("<html>Multi state on; call <a href=\"http://192.168.1.200:80/getpicturesmulti\">http://192.168.1.200:80/getpicturesmulti</a> to get pictures every two seconds.</html>");
                }
                else if (responder.UrlParameters["ledstate"].ToString() == "offmulti")
                {
                    WebServer.DisableWebEvent(webEventGetPicturesMulti);
                    led.TurnGreen();
                    responder.Respond("Multi state off");
                }
            }
        }

        void webEventGetPicturesMulti_WebEventReceived(string path, WebServer.HttpMethod method, Responder responder)
        {
            if (pictureForService != null)
                responder.Respond(pictureForService);
            if (camera.CameraReady)
                camera.TakePicture();
        }
    }

}
Advertisement
  1. #1 by luminarius on October 17, 2011 - 9:04 AM

    Using the startStreamingBitmaps method of camera, how can I efficiently stream these to the web without the autorefresh? I can stream pictures to the local display but not the web. Basically, is the device capable of streaming low res video?

    thanks

    • #2 by Michael Dodaro on October 17, 2011 - 9:27 AM

      The GTM.Module.NetworkModule.Responder responder object is generated by Gadgeteer.Modules.Module.NetworkModule.WebEvent.WebEventReceived in the GTM.Module.NetworkModule.WebEvent.ReceivedWebEventHandler. The event is raised when the client sends a request. Right now the closest thing to what you want to do would be the scenario demonstrated in the example with at refresh rate of 1 second. This part of the platform is still in testing, so more methods may be available after a while.

  2. #3 by workhard10 on January 25, 2012 - 8:01 AM

    hello,

    how can I configure my router and DNS to support it.

    as follow webaddresses?

    //http://129.186.1.200/takepicture

    //http://129.186.1.200/getsinglepicture

    //http://129.186.1.200/led?ledstate=onmulti

    //http://129.186.1.200/led?ledstate=offmulti

    //http://129.186.1.200/getpicturesmulti

    I have runned your project code aber I got nothing from the web after typing “http://129.186.1.200/takepicture” or any other webaddresses. why ?

    How can I do it?

  3. #4 by Michael Dodaro on January 25, 2012 - 8:10 AM

    I don’t thinik you have to configure your router to test this app. Make sure you have the right IP address from this line of code:
    Debug.Print(“IP address: ” + ethernet.NetworkSettings.IPAddress);

    Then put that addess in this method call:
    WebServer.StartLocalServer(“192.168.1.200”, 80);

    Be sure to push the button before you send the takepicture request url.

    This application, as it is, only works on local network. If you want to make it work on the Internet, then you do have to use something like http://www.dyndns.com/ and configure your router to support it. If you do that, you even have a domain name for Gadgeteer for free.

  4. #5 by workhard10 on January 27, 2012 - 7:49 AM

    Hello sir,
    I have several questions about the example.
    it semms that I can’t show a picture in the reply, so I send you an Email.

    I look forward to your answer.

  5. #6 by workhard10 on January 31, 2012 - 2:22 AM

    hello sir,

    I tried the example again and again,

    I always have the misstake in my “output windows”:

    Invalid native checksum: GHIElectronics.NETMF.Net 0xB7F1767D!=0x310788CC

    Resolving.

    Link failure: some assembly references cannot be resolved!!

    Assembly: Gadgeteer.WebServer (2.41.0.0) needs assembly ‘Gadgeteer’ (2.41.0.0)

    Assembly: Gadgeteer.WebServer (2.41.0.0) needs assembly ‘System’ (4.1.2821.0)

    Assembly: Gadgeteer.WebServer (2.41.0.0) needs assembly ‘System.IO’ (4.1.2821.0)

    Assembly: Microsoft.SPOT.Touch (4.1.2821.0) needs assembly ‘Microsoft.SPOT.Graphics’ (4.1.2821.0)

    Assembly: Microsoft.SPOT.Touch (4.1.2821.0) needs assembly ‘Microsoft.SPOT.Hardware’ (4.1.2821.0)

    Assembly: GTM.GHIElectronics.Camera (4.1.1.0) needs assembly ‘Gadgeteer’ (2.41.0.0)

    Assembly: GTM.GHIElectronics.Camera (4.1.1.0) needs assembly ‘GHIElectronics.NETMF.USBHost’ (4.1.8.0)

    Assembly: GTM.GHIElectronics.Camera (4.1.1.0) needs assembly ‘GHIElectronics.NETMF.System’ (4.1.8.0)

    Assembly: GTM.GHIElectronics.Camera (4.1.1.0) needs assembly ‘Microsoft.SPOT.Graphics’ (4.1.2821.0)

    Assembly: GTM.GHIElectronics.Camera (4.1.1.0) needs assembly ‘Microsoft.SPOT.Hardware’ (4.1.2821.0)

    Assembly: GTM.GHIElectronics.MulticolorLed (4.1.1.0) needs assembly ‘Gadgeteer’ (2.41.0.0)

    Assembly: Microsoft.SPOT.Net (4.1.2821.0) needs assembly ‘Microsoft.SPOT.Hardware’ (4.1.2821.0)

    Assembly: System.Net.Security (4.1.2821.0) needs assembly ‘System’ (4.1.2821.0)

    Error: a3000000

    Waiting for debug commands…

    Das Programm “[19] Micro Framework application: Verwaltet” wurde mit Code 0 (0x0) beendet.

    Do you have any idea?? why happend this?

    If the example runs good, how it look like?

  6. #8 by wintonlin on May 13, 2012 - 11:16 PM

    Hi, Michael
    How can I not just see a picture, but see a video stream on the client?
    Like a IP CAM

    • #9 by Michael Dodaro on May 14, 2012 - 9:15 AM

      You can stream successive bitmaps, but gadgeteer does not support video streaming.

  1. .NET Gadgeteer temperature logger example « Steven Johnston

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: