Camera connected not firing if my SD card is already inserted at start-up

I have a very simple ProgramStarted method:

        
void ProgramStarted()
{
      Debug.Print("Program Started");
     camera.CameraConnected += new Camera.CameraConnectedEventHandler(camera_CameraConnected);
}

My project is a simple camera with a button, screen, camera, and an SD card reader. If I start the project with the card not inserted into the reader all is good, the CameraConnected event fires and calls my camera_CameraConnected handler. But if I start with the SD card inserted in the reader the CameraConnected event does not fire and my camera_CameraConnected handler is never called. Any ideas why?

Any other errors or exceptions in the output window?

P.S. Please use code tags for code snippets.

1 Like

I just get:

Very unusual and I have never heard of something like that. Try to unplug other modules see if it makes a difference. Try running without debugger attached.

I am just guessing here.

Looking in the constructor code for the SD card at http://gadgeteer.codeplex.com/SourceControl/changeset/view/24955#256638 I see that if there is an SD card already in the slot it calls MountSDCard which in turn includes a thread sleep of 500ms. I wonder if that’s the problem?


public void MountSDCard()
{
    if (!IsCardMounted)
    {
        try
        {
            //_storage = new PersistentStorage("SD");
            //_storage.MountFileSystem();
            Mainboard.MountStorageDevice("SD");
            IsCardMounted = true;
            Thread.Sleep(500);
        }
        catch
        {
            ErrorPrint("Error mounting SD card - no card detected.");
        }
    }
}

I think I can reproduce this error with very little code.


using Microsoft.SPOT;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace MinimalCameraConnectedError
{
    public class Program : Gadgeteer.Program
    {
        Gadgeteer.Modules.GHIElectronics.Camera camera;
        Gadgeteer.Modules.GHIElectronics.SDCard sdCard;
        public static void Main()
        {
            Mainboard = new GHIElectronics.Gadgeteer.FEZSpider();
            Program program = new Program();
            program.InitializeModules();
            program.ProgramStarted();
            program.Run();
        }
        private void InitializeModules()
        {	
            camera = new GTM.GHIElectronics.Camera(3);
            sdCard = new GTM.GHIElectronics.SDCard(5);
        }
        private void ProgramStarted()
        {
            Debug.Print("Program Started");
            camera.CameraConnected += new Camera.CameraConnectedEventHandler(camera_CameraConnected);
        }
        private void camera_CameraConnected(Camera sender)
        {
            Debug.Print("Camera connected fired");
        }
    }
}

If there is no SD card in the slot when the above code runs I see the following lines in the output window:

But with an SD card in the slot at start-up all I see is:

My solution to this problem (bug?) is to abandon the CameraConnected event and use a timer instead:


using Microsoft.SPOT;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace MinimalCameraConnectedError
{
    public class Program : Gadgeteer.Program
    {
        Gadgeteer.Modules.GHIElectronics.Camera camera;
        Gadgeteer.Modules.GHIElectronics.SDCard sdCard;
        public static void Main()
        {
            Mainboard = new GHIElectronics.Gadgeteer.FEZSpider();
            Program program = new Program();
            program.InitializeModules();
            program.ProgramStarted();
            program.Run();
        }
        private void InitializeModules()
        {	
            camera = new GTM.GHIElectronics.Camera(3);
            sdCard = new GTM.GHIElectronics.SDCard(5);
        }
        private void ProgramStarted()
        {
            Debug.Print("Program Started");
            var timer = new GT.Timer(100);
            timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
            timer.Start();
        }
        void timer_Tick(GT.Timer timer)
        {
            if (camera.CameraReady)
            {
                timer.Stop();
                initCamera();
            }
        }
        private void initCamera()
        {
            Debug.Print("Camera now connected");
        }
    }
}

and with that code I see the output

regardless of whether the SD card is in the slot at start-up.

Looks like the event was discarded before it was delivered or never fired at all. Do you have another card maybe smaller in size to try?

Would the Program object going out of scope in the Main() method have any impact?

Run never returns.

Ah!

I’m not sure a smaller card would help since I need the code to be robust for large cards. Do you have any thoughts about the Thread.Sleep in the GHI code?

the small card suggestion is about eliminating aspects, and is not a “solution” but just something we’d like you to try…

I’ve now tried three SD cards, one 4GB, one 2GB, and one 128MB. They all cause the camera connected event to fail to fire. Would you like me to try anything smaller?

Yes please, down to 16 or 8mb of you can. No, of course I’m joking.

So if you don’t have the sd card in and you don’t have camera connected, and start the app everything runs normally and inserting those in any order makes no difference? Can you tell us what camera you have?

Sorry Brett - what do you mean by “don’t have the camera connected”? The camera remains physically connected to slot 5 (as the code shows?) throughout the entire process. The camera is this one: http://www.ghielectronics.com/catalog/product/283 (from the FEZ Spider Starter Kit)

ok, it’s technically a USB camera, so I meant you could use it as a USB device and plug/unplug as needed. But in the case where you’re connecting it via a Gadgeteer cable (the usual way for this device, and the way you have it) you wouldn’t want to disconnect it. So the question is, when you don’t have SD card in and you run the app, then insert the SD card, do all the events fire as expected?

Further to this, why do you want a Camera Connected event ? If you think about it, it’s only meant to be fired when the camera is an actual USB device and gets connected. I note your timer is just waiting for camera to report ready, is there an equivalent connected property ?

Brett, you ask “the question is, when you don’t have SD card in and you run the app, then insert the SD card, do all the events fire as expected”. Let me quote my post at the start of this thread “If I start the project with the card not inserted into the reader all is good, the CameraConnected event fires and calls my camera_CameraConnected handler. But if I start with the SD card inserted in the reader the CameraConnected event does not fire and my camera_CameraConnected handler is never called” I think that answers your question, doesn’t it? Your other question is “why do you want a Camera Connected event”? It seems to be usual practise (for example in the tutorial code at GHI Electronics – Where Hardware Meets Software) to use the CameraConnectedEventHandler to delay any code that requires the camera until after the camera is initialized. As I point out earlier in this thread I can do that with a timer checking the CameraReady property but that feels a bit of a hack when GHI provide a CameraConnected event.

No Andre that is false. I am using the Visual Studio C# Express 2010 .Net Gadgeteer Application (NETMF 4.2) project template. For the code sample I posted I thought it would be useful to move all the code from the auto-generated partial class into one non-partial class so that I could post all the code. Sorry if that’s confused things. This is a very very simple out-of-the-box Gadgeteer project, the simplest I could think of that still manifests the error.

Am I right in thinking that you guys do not see this error with this simple code? Or is the error reproducible for you too?