Button Module debouncing

Hello,

i am new in this Forum and this is my first thread.

I have a problem with the deboucing of standart button module.

At first, here is my code:


bool saveMode = false;
        
        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

            button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);

        }

        void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
                if (state == Button.ButtonState.Pressed)
                {
                    Debug.Print("My Button is pressed");
                    DoIt();
                }
                else
                {
                    Debug.Print("My Button is not pressed");
                }
        }


        void DoIt()
        {
            if (saveMode == false)
            {
                Debug.Print("On");
                saveMode = true;
                button.TurnLEDOn();
            }
            if (saveMode == true)
            {
                Debug.Print("Off");
                saveMode = false;
                button.TurnLEDOff();
            }
        }

Output:

The buttonPressed method set directly the saveMode on and off with one press, but actually, it should be this:

  1. press: Save Mode on
  2. press: Save Mode off

I believe that it is up to the debouncing, but how can I avoid or resolv it?

Welcome to the forum.

Change

if (saveMode == true)
            {
                Debug.Print("Off");
                saveMode = false;
                button.TurnLEDOff();
            }

To

else if (saveMode == true)
            {
                Debug.Print("Off");
                saveMode = false;
                button.TurnLEDOff();
            }
1 Like

And you should just be able to change:


void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
                if (state == Button.ButtonState.Pressed)
                {
                    Debug.Print("My Button is pressed");
                    DoIt();
                }
                else
                {
                    Debug.Print("My Button is not pressed");
                }
        }

to

void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
             
                    Debug.Print("My Button is pressed");
                    DoIt();
               
        }

Thanks for help.

else if

was the snipped i needed.

To simple…

Tnaks you very much.

Your welcome

There is one more problem.

I want save mensure ( potentiometer modul ) into a textfile on sd card.
The read mensured data any 100ms.

It is no problem to set the saveMode on and it is no problem to save my data into the textfile,
but if i want to set the saveMode off, the pressed button (module) dont respond to my buttonPressed code.
But if he responds, it will switch the save mode directly on, off, on, and never off.


SDCard c_SDCard;
        bool saveMode = false;
        string s_DateTime;
        GT.Timer timer;
        double voltage = 0;
        static string _dataFilePath = @ "\test.txt";        

        void ProgramStarted()
        {
            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
            // timer for mensure (100 ms)
            timer = new GT.Timer(100);
            timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
            timer.Start();

            button2.ButtonPressed += new Button.ButtonEventHandler(button2_ButtonPressed);

            sdCard.SDCardMounted += new GTM.GHIElectronics.SDCard.SDCardMountedEventHandler(sdCard_SDCardMounted);
            sdCard.SDCardUnmounted += new GTM.GHIElectronics.SDCard.SDCardUnmountedEventHandler(sdCard_SDCardUnmounted);
            // new object of class SDCard
            c_SDCard = new SDCard(sdCard);
            //set Storage Device in class SDCard
            if (sdCard.IsCardMounted)
                c_SDCard.SetStorageDevice(sdCard.GetStorageDevice());

        }

        void button2_ButtonPressed(Button sender, Button.ButtonState state)
        {
            if (sdCard.IsCardMounted && sdCard.IsCardInserted)
            {
                if (saveMode == false)
                {
                    //set saveMode on when button is pressed and saveMode = false
                    saveMode = true;
                    button2.TurnLEDOn();
                    Debug.Print("SaveMode auf on geschaltet");
                }

                else if (saveMode == true)
                {
                    //set saveMode off when button is pressed and saveMode = true
                    saveMode = false;
                    button2.TurnLEDOff();
                    Debug.Print("SaveMode wird off geschaltet");
                }
            }
        }

        void sdCard_SDCardUnmounted(GTM.GHIElectronics.SDCard sender)
        {
            Debug.Print("SD Card unmounted.");
            c_SDCard.SetStorageDevice(null);
        }

        void sdCard_SDCardMounted(GTM.GHIElectronics.SDCard sender, GT.StorageDevice SDCard)
        {
            Debug.Print("SD Card mounted.");
            if (sdCard.IsCardMounted)
                c_SDCard.SetStorageDevice(sdCard.GetStorageDevice());
        }

        void timer_Tick(GT.Timer timer)
        {
            //read input data (mensure)
            voltage = potentiometer.ReadPotentiometerVoltage();
            //save mensure, time to sd-Card
            if (saveMode == true)
            {
                s_DateTime = DateTime.Now.ToString("HH:mm:ss,ff");
                c_SDCard.StoreResult(voltage, s_DateTime, _dataFilePath);
            }
        }

And here the class which i use to handle sd-card methods:



    class SDCard
    {
        private GT.Modules.GHIElectronics.SDCard sdCard;
        GT.StorageDevice _storage;

        public SDCard(GT.Modules.GHIElectronics.SDCard sdCard)
        {
            this.sdCard = sdCard;
        }

        public void SetStorageDevice(GT.StorageDevice _storage)
        {
            this._storage = _storage;
        }

        public void StoreResult(double voltage, string s_DateTime, string _dataFilePath)
        {
            if (_storage != null)
            {
                try
                {
                    StreamWriter sw = new StreamWriter(_storage.RootDirectory + _dataFilePath, true);
                    sw.WriteLine(s_DateTime + "\t" + voltage.ToString());
                    sw.Flush();
                    sw.Close();
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.Message);
                }
            }
        }
    }



I believe it with the button to the timer interval has a problem. But i dont know why. Any idea?

What happens if you increase the timer to say 1000ms?

Then the memory mode is working properly.

However, the reading must be receptive every 100ms, 1000ms is to low.

so it works fine at 1000ms but not at 100ms?

What board are you using?

You need to see where the bottleneck is - perhaps write to the SD every 10 or more readings would be my guess

Thats right, 500ms is to slow, too.

I use the FEZ Spider Board with the 4.1 Framework.

Ok, i tried your proposal, its the same.
And without saving on sdcard, its the same too.
Can it be that I would have to press the button in 100ms to make it work? Its not possible. 1000ms are ok, but not 100 :slight_smile:

Sounds a bit strange - and no you dont want to be pressing the button every 100ms!

So you just need to read a analog sensor every 100ms and buy pressing a button turn saving on/off ?

I have a spider and if i can find 5mins i will try some code.

Thats right.

The measurement is always running and the store is to be switched on or off at some point.

I have to say that now I try to use a potentiometer but later the data on uart must be read every 100ms.
But I do not think it makes a difference.

Ok, thanks.

One more information:

With two buttons, its no problem, but I have to use ONE button.

cache the read results, put the results in an array. Once that array is full (of say 16 or 32 reads), or you otherwise want to terminate then write it to sd card.

Its not a problem to save, i have the same problem, when i only read analog data and press the button without the save method.

sorry, then you’re going to have to show us your code. Sounds like a code problem.

Do you really need to save 10 samples a second of analog input? Can you describe the reason you want to do this? Hope you realise that these are not precision ADCs you’re using, and there’s nothing that says the changes you see in between readings in that 100ms are actually accurate changes.

You’re also talking about needing some specific timing requirements. The #1 thing you should take away from this conversation is that NETMF is not real time and you can’t guarantee anything timing-wise. The garbage collector will kick in when it wants and it’ll take a chunk of time you can’t control (except by writing efficient code that doesn’t let the GC clean up after it). If you think you have challenges now, perhaps you’d best tell us more about your full requirements to make sure you’re not headed for a disaster.

I show and explain it on monday.