If you want to use a MOSFET as a power switch, then it might be easier to use an N-Channel MOSFET instead. Connections for it are more straight forward and easier to understand. I have an article that explains why you may want to prefer an N-Channel MOSFET:
https://circuitjournal.com/which-mosfet-should-you-use-with-arduino

P-Channel MOSFET and Arduino. Switching a 12V Motor.

Connecting a P-Channel MOSFET to an Arduino can be a little trickier than an N-Channel MOSFET, but if you understand how it works, then it's not very complicated.

The main thing to understand about P-Channel MOSFETs is that they activate when the voltage on the Gate terminal is lower than the Source. It means that the Source of the MOSFET must be connected to the 5V output of the Arduino. Then the Arduino output pin LOW can be lower than the Source.

Symbols for P-Channel MOSFETs:

P-Channel MOSFET Gate-Source voltage

To simplify things, I am giving all the examples for the more common Enchantment-Type ("Normally OFF") MOSFETs - these are not conducting electricity when the voltage between the Gate and the Source (Vgs) is zero. The alternative Depletion-Type ("Normally ON") MOSFETs are a logical inversion of that. You can apply all the same examples and rules for a Depletion-Type MOSFET. Just the ON/OFF status is reversed.

In this article, I am going to explain all the necessary connections (and related dangers) to create the following diagram. And how to then control the power of the motor with an Arduino output pin.

P-Channel MOSFET connection diagram. Connected on the VCC side.

To follow this tutorial, you need:

  • A P-Channel MOSFET
  • A 10kΩ pull-up resistor
  • A flyback diode
  • A bunch of jumper wires
  • A breadboard
  • An Arduino or Arduino compatible board

Video Tutorial

A step-by-step guide about using a P-Channel MOSFET with an Arduino to switch a 12V motor ON and OFF.

P-Channel MOSFET on the 12V (VCC) Side of the Load

Let's say you want to turn ON and OFF a 12V DC motor using an Arduino and a P-Channel MOSFET.

The most intuitive way to archive this goal is to wire the MOSFET on the VCC side of the load (the motor in this case).

P-Channel MOSFET connection diagram. Connected on the VCC side.

You need to have two power sources - one for the Arduino, and a separate 12V power source for the motor.
You cannot connect the Arduino's barrel jack to the 12V! This will create a common ground between your Arduino and the 12V power supply. And it would fry the Arduino when you are creating the common VCC needed for this circuit. (With an N-Channel MOSFET you don't have this problem since you want to have a common ground between the power source and the Arduino)

1. First, you need to create a Common VCC by connecting the positive output of the 12V power source to the Arduino 5V pin. DO NOT CONNECT THE GROUNDS!

2. Then connect the Source pin of the MOSFET to the VCC and the Drain pin to the positive lead of the motor.

Usually, you have common Ground between devices. But in this case, we need the Arduino to be able to put -5V on the Gate terminal of the P-Channel MOSFET. Connecting the Arduino 5V pin to the VCC (and the Source) will achieve this since now the Arduino output HIGH will be 0V on the Gate, and output low will be -5V on the Gate.

3. Connect the negative lead of the motor to the negative output of the 12V power supply.

4. With inductive loads (devices that have coils in them) like a motor, you need to add a flyback diode. It's a diode that is connected across the load in a reverse direction of the normal current flow. During motor operation, it doesn't do anything. But when the MOSFET switches OFF, the coil inside the motor will continue pushing electrons forward and will create a voltage spike. This can damage your MOSFET. The flyback diode allows the excess induced current to flow back and circulate inside the motor until all the energy is dissipated.

5. Add a 10k resistor between the Gate terminal and the VCC. It will ensure that the MOSFET is OFF while the Arduino pin is not initialized as OUTPUT yet, and is not actively driving the Gate (during startup, for example).

6. Finally, connect the Arduino digital output pin to the Gate.

P-Channel MOSFET on the Ground Side of the Load

I'll give this alternative connection diagram for educational purposes. Maybe it helps to understand the P-Channel MOSFET better.

You can also connect a P-Channel MOSFET below the load on the negative side of the power source. But here we don't have a common Ground nor a common VCC with the 12V power supply. Arduino 5V and GND pins are floating somewhere between the + and - outputs of the 12V power supply because there are no direct connections to them.

P-Channel MOSFET connection diagram. Connected on the GND side.

Since the MOSFET is activated or deactivated based on the voltage between the Gate and the Source, we need to make sure that the Arduino 5V pin is on the same level as the Source. So we need to connect the Source directly to the Arduino 5V pin.

It's the same case here that you cannot connect the grounds of the power supply and the Arduino! If you do that, you will apply more than five volts to the 5V pin (through the motor).

Arduino Code to Control the MOSFET

To drive a P-Channel MOSFET, you have to define one of the Arduino pins as OUTPUT and set it to HIGH to turn it OFF and set it to LOW to turn it ON.

HIGH state is OFF because the Source pin of the MOSFET is connected to the 5V output of the Arduino. It means that Vgs (voltage between the Gate and the Source) is 0V, and an Enchantment-Type MOSFET is turned OFF in this circumstance.

The following code will turn a motor ON and OFF every five seconds:

void setup() {
  // Set pin 6 as Digital Output
  pinMode(6, OUTPUT);
}

void loop() {
  // turn MOSFET OFF
  digitalWrite(6, HIGH);
  delay(5000)

  // turn MOSFET ON
  digitalWrite(6, LOW);
  delay(5000)
}

If you are controlling a motor or a lamp that can handle a PWM signal, then you can also use analog write command. For example, this will drive a motor at half the power or dim a LED light to 50 percent:

void setup() {
  // Set pin 6 as Digital Output
  pinMode(6, OUTPUT);
}

void loop() {
  // 50% duty cycle for pin 6 (255 is 100%)
  analogWrite(6, 127);
}