I am trying to make a touch switch using an Arduino and a MOSFET. I have managed to get an LED to turn on when the pad is touched and it seems to work well (fully on when I touch it and fully off when i don't). However, when I try to replace the LED for an Arduino pin pulled high (internally) I run into problems. Sometimes the switch is read as low when I touch the pad, but other times it just becomes unresponsive. Could anyone see where i am going wrong? Thanks.

enter image description here

  • \$\begingroup\$ I wonder whether you need an external pull up on the A0 pin. Have you definitely configured your pin (which I am assuming is A0) as an input pin? \$\endgroup\$
    – DiBosco
    Commented Feb 12, 2018 at 16:47
  • \$\begingroup\$ If you were using an LED directly connected to the Mosfet Drain and had success, that means you were allowing several mA to flow with contact. I'd suggest you need a lower value for the pull-up (than the internal one on the Arduino) resistor. Try something around 4k Ohms. The internal pull-up is from 20-50K Ohms. \$\endgroup\$ Commented Feb 12, 2018 at 17:11
  • \$\begingroup\$ Here is my arduino code:code#define input_pin A0 int input_data; void setup() { pinMode(input_pin,INPUT_PULLUP); Serial.begin(9600); } void loop() { input_data = analogRead(input_pin); Serial.println(input_data); delay(200); }code Jack, i tried your suggestion (changing the arduino code so that the pin is an input instead of a pullup) and had the same results. it seems to work and then it just becomes unresponsive.... \$\endgroup\$ Commented Feb 12, 2018 at 17:22

2 Answers 2


Your approach is deficient in several ways.

First, when you touch the pad with finger, you have huge AC signal coming in, 50/60Hz. When you release your finger, the gate charge can be left in any phase, positive, or negative. That's why your MCU reads low sometimes. More, huge AC amplitude likely stress the MOSFET input beyond voltage specifications, and some latchup occurs.

Second, it is very likely that your FET will be eventually destroyed by ESD.

To implement the idea of touch contactless buttons for various controls in electronic and household equipment, the Electronic Industry developed a special class of devices called touch sensors. They are not simple devices. Several semiconductor companies offer ICs that provide this function reliably. In many cases the touch sensor functionality is included in MCU directly. To get an idea, check this list on Digi-Key. This is a sample, directly for your application,

enter image description here

  • \$\begingroup\$ Thanks for this, the explanation for whats going on with the ac wave makes sense. could i perhaps use a series resistor at the gate to stop it from becoming destroyed and rectify the ac wave? \$\endgroup\$ Commented Feb 12, 2018 at 18:10
  • \$\begingroup\$ @user2105725, my point is that many people tried this simplistic approach, and it doesn't work. That's why many seasoned engineers came up with the sophisticated class of devices, touch sensors, to solve the problem. Don't waste your time and re-invent the wheel. \$\endgroup\$ Commented Feb 12, 2018 at 18:14
  • 1
    \$\begingroup\$ fair cop although reinventing the wheel is often quite good if you want to learn about how something works rather than just buying modules. point taken though and thanks for the help. \$\endgroup\$ Commented Feb 12, 2018 at 18:40
  • \$\begingroup\$ @user2105725, yes, you can add a rectifying diode, a resistor in series, and a ESD protection, something like TVS diode, with limits that are above the MOSFET gate threshold. It should work. Some MOSFETs have this protection already built in, you need to do some search. \$\endgroup\$ Commented Feb 13, 2018 at 2:01

In case anyone is interested, I have created a solution to my problem using Arduino code. So far it seems to work flawlessly. I have added a 5k resistor in series with the gate, to reduce the likelihood of harming the gate.

#define input_pin A0
#define led_pin 3

int input_data;
unsigned long timer;
bool setTimer;
bool touched = false;
bool first = true;
bool toggle = true;

void setup() {
  pinMode(input_pin, INPUT_PULLUP);
  pinMode(led_pin, OUTPUT);
void loop() {

  digitalWrite(led_pin, toggle);

  if (digitalRead(input_pin) == LOW) {
    touched = true; //set the variable on the first low which is read
    setTimer = true;

  if (touched == true && first == true) { //only allow it to happen once
    first = false;
    toggle = !toggle;

  if (setTimer == true) {
    timer = millis();
    setTimer = false;

  if (millis() - timer > 100) {
    first = true;
    touched = false;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.