Capacitive button using PulseFeedback

I have created a driver for a capacitive button using PulseFeedback:


public class CapacitiveTouchButton : GTM.Module
    {
        private PulseFeedback capacitiveButton;
        private ButtonEventHandler onButtonEvent;

        /// <summary>Represents the delegate that is used to handle the <see cref="ButtonReleased" /> and <see cref="ButtonPressed" /> events.</summary>
        /// <param name="sender">The <see cref="Button" /> object that raised the event.</param>
        /// <param name="state">The state of the Button</param>
        public delegate void ButtonEventHandler(CapacitiveTouchButton sender, ButtonState state);

        /// <summary>Raised when the button is released.</summary>
        public event ButtonEventHandler ButtonReleased;

        /// <summary>Raised when the button is pressed.</summary>
        public event ButtonEventHandler ButtonPressed;

        /// <summary>
        /// Capacitive Touch Button
        /// </summary>
        /// <param name="socketNumber">The Gadgeteer socket used</param>
        /// <param name="pin">The GPIO pin used</param>
        public CapacitiveTouchButton(int socketNumber, int pin)
        {
            var socket = Socket.GetSocket(socketNumber, true, this, null);
            socket.EnsureTypeIsSupported(new char[] { 'X', 'Y' }, this);

            capacitiveButton = new PulseFeedback(PulseFeedback.Mode.DrainDuration, true, 10, socket.CpuPins[pin]);
            DrainDuration = 90;

            Thread PollThread = new Thread(PollButtonState);
            PollThread.Start();

        }

        /// <summary>The state of the button.</summary>
        public enum ButtonState
        {

            /// <summary>The button is pressed.</summary>
            Pressed = 0,

            /// <summary>The button is released.</summary>
            Released = 1
        }

        /// <summary>Whether or not the button is pressed.</summary>
        public ButtonState CurrentState { get; private set; }


        /// <summary>
        /// The drain duration needs to be customised for the resistor and capacitor and actual sensitivity required
        /// </summary>
        public long DrainDuration { get; set; }

        void PollButtonState()
        {
            var lastState = ButtonState.Released;
            while (true)
            {
                var durationFeedback = capacitiveButton.Read();
                //Debug.Print(durationFeedback.ToString());
                if (durationFeedback > DrainDuration) 
                {
                    CurrentState = ButtonState.Pressed;
                }
                else
                {
                    CurrentState = ButtonState.Released;
                }


                if (CurrentState != lastState)
                {
                    Debug.Print(CurrentState.ToString());
                    OnButtonEvent(this, CurrentState);

                }
                lastState = CurrentState;


                Thread.Sleep(250);
            }
        }


        private void OnButtonEvent(CapacitiveTouchButton sender, ButtonState state)
        {
            if (this.onButtonEvent == null)
                this.onButtonEvent = this.OnButtonEvent;

            if (Program.CheckAndInvoke(state == ButtonState.Released ? this.ButtonReleased : this.ButtonPressed, this.onButtonEvent, sender, state))
            {
                switch (state)
                {
                    case ButtonState.Released: this.ButtonReleased(sender, state); break;
                    case ButtonState.Pressed: this.ButtonPressed(sender, state); break;
                }
            }
        }
    }

Which can be used like so:


        private void ProgramStarted()
        {
            var testbutton = new CapacitiveTouchButton(10, 3);
            testbutton.ButtonPressed += testbutton_ButtonPressed;
        }

        void testbutton_ButtonPressed(CapacitiveTouchButton sender, CapacitiveTouchButton.ButtonState state)
        {
            Debug.Print("Hello");
        }

However I am struggling with the hardware side.
I have a 1M ohm resistor between pin 3 and ground, a 22pf capacitor between pin 3 and ground (although I am not sure if this is needed) and a wire with a piece of copper tape attached to pin 3.

The durationFeedback is around 60 when nothing is touching the copper tape and around 100 when you are physically touching the copper tape.

I need to be able to sense someone’s finger presence through 1mm Perspex (to keep the electronics environmentally sealed) but at the moment I am not getting any form of result what so ever.

The document https://www.ghielectronics.com/docs/326/pulse-feedback is of no help as it shows a diagram and then says something totally different in the text beneath!

Can anyone see where I am going wrong?

@ networkfusion -

I do not know that much about Touch Pads but you may want to look at the
BrainPad schematic and the code in BrainPad.cs.

Touch works well on my BrainPad.

Just a thought…

@ willgeorge - Thanks, I have looked at BrainPad.cs and cannot see anything untoward with my code… but since the code is legacy, I am having trouble finding a schematic for the version you must be using…

@ networkfusion - Sorry about that, the image in the document has been corrected.

@ John - Thanks, so could it be the missing 330 ohm resistor not being there that is causing my issue?
Does it matter how small/large the touchpad is?
Is a 22pf cap (which is the only value I have in the pf range lying around) too small?

I do not think it should matter too much.

From our experiments, the larger the capacitor, the longer it takes to discharge so it may work.