Cerbuinobee, builtin SD card, detect eject

Is there a way to detect when an SD card has been ejected with the built in SD card on the Cerbuino bee?

I tried the RemovableMedia.Eject event but that is not called.

I did not find any direct way so I tried to detect it in a round about way.

My application is a simple serial port data logger and the user can remove the SD card at any time. I simply put a try block around



to detect if a card is prestent and then allow logging to start. 

I was hoping to put a try block around the calls to writing to the SD card that would catch an exception if the crad was removed while writing. Unfortunatley, that seems to crash the program and not catch the exception at all. Here is some test code. It tries to write every 5 seconds. After a successfull write I remove the card. The program just crashes without throwing any exception to the Output window


```cs
using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;

using GHI.OSHW.Hardware;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using System.IO.Ports;
using System.IO;

namespace LIN_Logger_Cerbuino
{
    public partial class Program
    {
        SerialPort ComPort;
        private GT.Timer _timer;
        private string _root;
        private bool _SDMounted = false;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
            
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
            
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/


            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
            RemovableMedia.Eject +=new EjectEventHandler(RemovableMedia_Eject);
            RemovableMedia.Insert+=new InsertEventHandler(RemovableMedia_Insert);
            _timer = new GT.Timer(5000);
            _timer.Tick += new GT.Timer.TickEventHandler(TimerTick);
            _timer.Start();
        }

        void RemovableMedia_Insert(object sender, MediaEventArgs e)
        {
            Debug.Print("SD card inserted");
        }

        void RemovableMedia_Eject(object sender, MediaEventArgs e)
        {
            Debug.Print("SD card ejected");
        }

        private bool MountSD()
        {
            if (_SDMounted)
            {
                return true;
            }

            try
            {
                GHI.OSHW.Hardware.StorageDev.MountSD();
                _SDMounted = true;
            }
            catch
            {
                Debug.Print("No SD Card");
                _SDMounted = false;
                return false;
            }

            try
            {
                if (VolumeInfo.GetVolumes()[0].IsFormatted)
                {
                    _root = VolumeInfo.GetVolumes()[0].RootDirectory;
                }
            }
            catch
            {
                _SDMounted = false;
            }

            return _SDMounted;
        }

        void TimerTick(GT.Timer timer)
        {
            Debug.Print("Tic Toc");
            Stream stream;

            if (MountSD())
            {
                Debug.Print("Have SD Card");

                string fileName = Path.Combine(_root, "file.txt");

                try
                {
                    if (VolumeInfo.GetVolumes()[0].IsFormatted)
                    {
                        _root = VolumeInfo.GetVolumes()[0].RootDirectory;
                    }
                    Debug.Print("Got Root");
                    if (File.Exists(fileName))
                    {
                        stream = File.OpenWrite(fileName);
                        stream.Position = stream.Length;
                    }
                    else
                    {
                        stream = File.Create(fileName);
                    }
                    using (var writer = new StreamWriter(stream))
                    {
                        writer.WriteLine(Guid.NewGuid().ToString());
                    }
                    stream.Dispose();
                }
                catch
                {
                    Debug.Print("Failed to Write File");
                    _SDMounted = false;
                }
            }
            else
            {
                Debug.Print("No SD Card");
            }

        }
    }
}

There is a pin on the Cerbuino that will allow you to detect if the card is inserted, it is PC2. This pin can be polled and/or maybe even have an interrupt associated with it to let the system know that the card is inserted or not.

2 Likes

I used this approach with .net 4.2 and just migrated to 4.3. How do you access PC2 under 4.3? The FEZCerbuinoBee.Pins class does not have these pins defined?