Controling mini vibration motors with mosfet instead of bjt

I have two questions regarding controlling motors:

  1. I'm controlling those mini vibration motors using npn transistor with the following circuit:

I also tried controlling them using a logic-level MOSFET with the following circuit, and it worked just fine:

Why choose one circuit over the other? BJT transistors are cheaper, but with the same circuit (the MOSFET circuit), I could also drive solenoids with much higher current, which I can't do with a BJT. So, what I'm asking is: Can I also control the mini vibration motors with MOSFETs instead of BJT transistors? Is there any reason not to do so?

Assuming all of my motors (either mini vibration motors or solenoids) are far away from the Arduino itself (5-15 meters), what is the better approach? Should I place the drivers close to the motors (no more than 1 meter) and send long wires from the control pins of the Arduino and the Arduino ground? Or should I do the opposite? Should I use short wires from the Arduino GPIO pins and the Arduino ground and long two-wire connections to the motors?

  • It’s not wise to extend the Arduino GND out to 15m.

  • MOSFETs can power inductive loads, make sure you use kickback diodes across the inductor.

  • Consider an opto isolator or relay to control loads far away from your Arduino.

  • A properly selected MOSFET consumes much less power than a BJT.

1 Like

so better to have long wires from arduino to the motor and keep gpio and ground wires short rather the opposite..?

what about controlling the mini vibration motors with mosfet instead of bjt?

  • Keep the connection to your driver near the Arduino, i.e. the connection to the GPIO pin should also be short.

  • MOSFETs can drive vibration motors.

Do you know what a logic level MOSFET is ?

I think it is electrical device that can act as a switch (in order to switch load on and off that require large current (more then what an arduino gpio pin can deliver)) and can be control from the 5V output the arduino gpio pin can deliver

Yes.

If your Arduino operates at 3V3, the MOSFET needs to be able to turn on at 3V3.

Here are some MOSFET (logic level) part numbers I use:

If using optocoupler - which one you recommended? pc817 is ok? other part preferred?

That opto isolator should be okay.


Over the years I’ve settled on using 4N32

I have build this circuit on my breadboard trying to switch 580mA solenoid:

Nothing is happening. I have checked with DMM between pin 1 and 2 of the PC817 and when GPIO2 is HIGH I'm reading only ~1V . Does it make sense? what could be my mistake ?

Between pin 3 of the PC817 and GND2 I'm reading only 200mV when GPIO2 is HIGH ( Ishould read there around VCC1 (12V) ?

edit: I have lowered R1 from 470R to 270R and still - I'm reading only ~1V between pc817 pin 1 and arduino ground (GND1)

Yes, it should be 12V

Let’s see good images of the actual wiring.

Does the voltage on Opto pin 1 to Arduino GND toggle between 5v and 0v ?

Do you have a spare Opto ?

No, It toggle between 200mA and 1V.

Do you have a spare Opto ?

Yes, I already tries two. same results

:thinking:

When you connect the wire on Opto pin 1 to Arduino 5v, does Opto pin 3 to GND2 go to 12V ?

Yes!

here is my arduino code:
I also noticed that the arduino led (pin 13) should blink every 500ms but it is not happening.
something is wrong in my code?

const int NUM_PWM_MOTORS = 4;

const int pwm_motor_pins[] = {3, 5, 6, 9};
const char pwm_motor_ids[] = {'A', 'B', 'C', 'D'};

const int NUM_DIGITAL_MOTORS = 4;

const int digital_motor_pins[] = {2, 4, 7, 8};
const char digital_motor_ids[] = {'W', 'X', 'Y', 'Z'};
unsigned long heartbeatMillis;

int heartbeatLED = 13;

void setup() {
  Serial.setTimeout(10);
  Serial.begin(115200);
}
void loop() {
  checkHeartbeatTIMER();
  motorsControl();
}
void motorsControl() {
  if (Serial.available() > 0) {
    char id = Serial.read();
    int state = Serial.parseInt();
    for (int i = 0; i < NUM_PWM_MOTORS; i++) {
      if (id == pwm_motor_ids[i]) {
        analogWrite(pwm_motor_pins[i], state);
        Serial.print(id);
        Serial.print(" ");
        Serial.println(state);
      }
    }

    for (int i = 0; i < NUM_DIGITAL_MOTORS; i++) {
      if (id == digital_motor_ids[i])
      {
        digitalWrite(digital_motor_pins[i], state);
        Serial.print(id); Serial.print(" ");
        Serial.println(state);
      }
    }
  }
}
void checkHeartbeatTIMER() {
  if (millis() - heartbeatMillis >= 500) {
    heartbeatMillis = millis();
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }
}

ok I forgot to set the pin to output art setup.. lets check again...

Edit:
It is working!

R1 is left 270R. Shall I change back to 470R ?

I try both 470R and 270R and don't see really a difference. How do you know what to choose?

If the voltage on Opto pin 3 goes to 12v when R1 is 470, use 470.