Arduino as a flight controller resets under motor load using PWM signals and multiple transistors

I am developing a flight controller to learn more about drones but I am having issues when testing it under load.

The nano keeps resetting. It's LED either blinks rapidly, holds a solid light, or does nothing else. I know it's resetting because in my Loop code (below), I set the LED_BUILTIN to blink, which it ceases to do when I connect the motor.

I tried removing the LiPo to VIN pin for the Nano and powering it instead with a 9v battery but it still resets.

Here is my ideal setup:

  • Arduino nano as the flight controller which converts gyro data into PID output (converted to PWM to motors)
  • 5 nano digital pins set to PWM output using software PWM (GitHub - bhagman/SoftPWM: A Wiring (and Arduino) Library to produce PWM signals on arbitrary pins.)
  • 4 digital pins will control the power to each motor using PWM against a TIP142C transistor gate
  • 1 digital pin will control a 30n06 MOSFET to manage the motor power. My idea here was to pulse the power so that the nominal voltage comes down to 3.7 volts for the motors (2S LiPo battery) and also feed it into the VIN for the Nano. I can accomplish this with a 50% duty cycle on the gate of the mosfet. I also want to be able to burst up to 7 volts for short durations on the motors. So the ability to feed higher or lower nominal voltage to the motors is highly usable for me.
  • The LiPo battery is 2s with 20C at 450mAH

When I disconnect the motors and look under an oscilloscope, the gates are receiving the appropriate PWM signals. Only when connecting the motors does it reset the Nano.

Below is a schematic of my flight controller. Ignore the HCP and NRF as they are not connected. The gyro is connected. I apologise for the messiness - I am still learning how to use the software.

If it's not obvious from the schematic, here is a summary of the wiring:

  • Gates are pulled down with a 10k resistor to ground
  • Vin of the Nano and its ground are connected to the lipo's ground
  • LiPo (+) connects to each DC motor first in parallel
  • The (-) of the motors go to each transistor's collector
  • The emitters for the transistors go to the mosfet's source
  • The mosfet's drain goes to ground

Here is my code. I was testing to see if the power combinations of the PWM signals for the motor-transistors and the power-control mosfet were working correctly:

const uint8_t PIN_POWER = 3;
const uint8_t PIN_BL = 4;
const uint8_t PIN_FL = 5;
const uint8_t PIN_BR = 6;
const uint8_t PIN_FR = 7;
//
#include <SoftPWM.h>

void setup() {
    Serial.begin(115200);
  SoftPWMBegin();

  for (int i = 3; i < 8; i++) {
      SoftPWMSet(i, 0);
      // 0ms fade up and fade down
      SoftPWMSetFadeTime(i, 0, 0);
  }

    pinMode(LED_BUILTIN, OUTPUT);
    Serial.println("Began flight contrller");

   // blink 3 times to confirm ready
    for (int i = 0; i < 3; i++) {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(100);
        digitalWrite(LED_BUILTIN, LOW);
        delay(100);
    }
}

void loop() {
    setPower(0, false);
    setPins(0);

    setPower(25, false);
    setPins(0);
    setPins(25);
    setPins(50);
    setPins(75);
    setPins(100);
}
void setPins(int percent) {
    Serial.print("Setting pins to ");
    Serial.println(percent);
    for (int i = 3; i < 8; i++ ){
        if (i == PIN_POWER) continue; // skip power pin
        SoftPWMSetPercent(i, percent);
    }
    delay(3000);
}

void setPower(int percent, bool skip) {
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.print("Setting power to ");
    Serial.println(percent);
    SoftPWMSetPercent(PIN_POWER, percent);
    if (!skip) delay(3000);
    digitalWrite(LED_BUILTIN, LOW);
}

I guess that you missed the freewheel diodes over each motor.

Do you know that drones typically use BLDC motors for efficiency?

I had a similar problem. Your motors are putting a lot of noise on the VIN line. I added a 20 Ohm series resistor in the VIN line and after that a 1000 uF elco. That created a RC filter suppressing enough of the EM noise to make the MCU stable.
if 20 Ohm is too much, try 10 Ohm instead.

And I don't understand your wiring of Q1. Only 2 of 3 wires connected.

No current limiting resistor at the base of your PNP transistors?

Freewheel diodes are to prevent the collapse of the magnetic field when the current is cut off. While you're correct that they should be there, it's not the cause of my problem because my Arduino resets when the motors start up, not on the shut off. Though I should still add them to be safe, you're not wrong about that.

Brushless DC motors typically require electronic speed controllers since they are usually 3 phases. To eliminate the need for the half H bridges and also to make use of these motors lying around, I opted for DC motors. They're much lighter too

I'll try that 20 ohm trick. I mentioned that I tried removing the Vin connection to the LiPo and connecting it to a 9v battery separately to no avail. Do you think the noise still impacted the Arduino if it had a separated Vin line?

There isn't current limiting resistors between the transistors and the Arduino. Is that needed? I have pulldown resistors between the gates and ground.

And yes you're correct, my Q1 schematic is missing the wiring from its drain to ground. I wrote up a blurb below the schematic to highlight the functions

Are you sure it is PNP that you are using and not NPN transistors. Which exact part number are you using for transistors?

Through R6 you are feeding 2S lipo voltage to A0. That's a no-go, as you should not feed more than VCC to it.

my Arduino resets when the motors start up

Yes. Insufficient power supply decoupling, power conductors too small, or battery current capability too low.

Use separate power for motors and microcontrollers - otherwise you'll just be plagued with problems like this.

Sure. DC motors change their magnetic field during every rotation thus causing heavy EMF.

Right, their speed can be controlled easily. Brushed DC motors instead require feedback and a regulator for speed control.

I only see one gate, and a bunch of useless BJT darlingtons without base resistors.
No base resistors will overload/damage the Nano pins.

No, source of an N-channel fet should go to ground.
(I suppose you are trying to switch the four motor transistors off with that one).
Why not use four logic-level fets, and do the switching in software.
Leo..

Which exact part number are you using for transistors?

Shared in the post - 30n06 for the power and TIP142c for the motors

Through R6 you are feeding 2S lipo voltage to A0. That's a no-go, as you should not feed more than VCC to it.

You're correct - I forgot to add a voltage divider to the schematic, though I had it added to my circuit.

Thank you - I got it to work. A comment earlier suggested adding resistors between the digital pins and the transistor gate. After adding 330ohm resistors, the motors were spinning without the Nano resetting.

I have not tested it with all 4 motors at once yet so I believe the issues you brought up will definitely come up as I test further

The flyback diode is for addressing back EMF right? So startup is unaffected.

Brushed DC motors instead require feedback and a regulator for speed control.

I think you mean brushless?

No base resistors will overload/damage the Nano pins.

This ended up being the cause, thank you. I still need to address the lack of a flyback diode and the noise issue when the LiPo is connected to VIN, but at least it stopped resetting the Nano

Why not use four logic-level fets, and do the switching in software.

Can you suggest some parts? I don't have any but I can buy some. I only had these transistors laying around so I used them

Google "Arduino logic level mosfet". There are hundreds that could work.
Some have a letter "L" for "logic-level" in the model number, like the IRLZ44.
Add "datasheet pdf" to the model number in Google, and see if there is a source/drain resistance listed for 5volt. Or ask here before you order.
Leo..