N-Channel MOSFET - Current driver


I am using a 2kHZ PWM 0-5V signal 0-100% duty cycle to control a N-Channel MOSFET (IRL2910) . The idea is to control up to 3A of current through the drain/source. The principle works fine but the current fluctuates by around 150mA. Is there a better design or would you know of a better MOSFET I could use to get impoved accuracy? A current shunt is being used to measure the current output.


Thanks in advance!

So many unanswered questions here. What is the load? What is the driver? How are you measuring the shunt voltage at the JST? At what duty cycle does it fluctuate 150mA?

What's the load? Inductive?

What's the PWM TOP value?
How do you control the PWM duty cycle?

#2 & 3:
The load is a vehicle damper. The driver to create the PWM is ATiny85. The shunt voltage is measured on a scope 75mV for a 3A current. The PWM is being controlled using a 10 turn, 10K potentiometer. There isn't a specific region where the 150mA fluctuation is occuring. It appears across the 0-3A scale quite randomly. I've looked at the PWM signal and it is rock steady. I'm unsure if it's the MOSFET causing this or if I could add something to the circuit to improve it?

Does the scope show the PWM output of the ATtiny85 being adjusted by the pot?
What does the scope see on the drain of the MOSFET.
Is the damper/shocker an inductive load?
Can you post link to specs/data of the damper?
What is the supply voltage to the damper and is its gnd connected to the ATtiny85 gnd.

Please post a complete circuit including power supplies.

Can you post your code please?

Tom... :grinning: :+1: :coffee: :australia:

The scope does show the varying PWM from the ATiny85. It also shows the 12V on the drain of the MOSFET. The supply voltage to the damper is a nominal 12V DC.
The damper is an inductive load. I don't have the spec of the damper unfortunatly.
The ATiny ground and damper ground are shared.
Damper Current Controller.pdf (242.3 KB)

       RST - A0 - (D 5) --| 1 PB5   VCC 8 |-- +5V
                          |               |
500Hz SW I/P A3 - (D 3) --| 2 PB3   PB2 7 |-- (D 2) - A1  --> 10K Potentiometer
                          |               |
1kHZ SW I/P  A2 - (D 4) --| 3 PB4   PB1 6 |-- (D 1) - PWM --> Damper Circuitry
                          |               |
                   Gnd ---| 4 GND   PB0 5 |-- (D 0) - PWM --> 2Khz SW I/P 

// normal delay() won't work anymore because we are changing Timer1 behavior
// Adds delay_ms and delay_us functions
#include <util/delay.h>

// Clock at 8mHz
#define F_CPU 8000000  //F_CPU 8000000. This is used by delay.h library

const int PWMPin = 1;  // Only works with Pin 1(PB1)
const int PotPin = A1;
const int fivehundredhertz_select = 3;
const int onekilohertz_select = 4;
const int twokilohertz_select = 0;

// variables will change:
int selectionState1 = 0;// variable for reading the 500Hz selection
int selectionState2 = 0;// variable for reading the 1KHz selection
int selectionState3 = 0;// variable for reading the 2KHz selection

void setup()
  pinMode(PWMPin, OUTPUT);
  pinMode(fivehundredhertz_select, INPUT);
  pinMode(onekilohertz_select, INPUT);
  pinMode(twokilohertz_select, INPUT);

  //Use FAST PWM
  TCCR0A = 1 << COM0B1 | 0 << COM0B0 | 1 << WGM01 | 1 << WGM00;
  TCCR0B = 1 << WGM02;

     8 000 000 / 64 = 125 kHz
    64 - pre-scaler
    125 kHz / 63 ~ 2000 Hz
    63 - OCR0A
  // disable interrupts
  TIMSK = 0;

  // set TOP to generate ~2 kHz
  OCR0A = 63;// 63=2Khz, 127=1Khz, 500hz=255

  // 50% duty cycle
  OCR0B = 31;//31

  // start timer at 125 kHz (8 MHz / 64)
  TCCR0B = 1 << WGM02 | 0 << CS02 | 1 << CS01 | 1 << CS00;


void loop()
  int in, out;

  in = analogRead(PotPin);

  //  out = map(in, 0, 1023, 0, 63);//(in, 0, 1023, 0, 1023) LINE ADDED

  // read the state of the input selections:
  selectionState1 = digitalRead(fivehundredhertz_select);
  selectionState2 = digitalRead(onekilohertz_select);
  selectionState3 = digitalRead(twokilohertz_select);
  if (selectionState1 == HIGH)
    OCR0A = 255;//500 hz
    out = map(in, 0, 1023, 0, 255);//(in, 0, 1023, 0, 255)
    ;//Do nothing

  if (selectionState2 == HIGH)
    OCR0A = 127;//1Khz(127)
    out = map(in, 0, 1023, 0, 127);//(in, 0, 1023, 0, 127)
    ;//Do nothing

  if (selectionState3 == HIGH)
    OCR0A = 63;//2Khz 63
    out = map(in, 0, 1023, 0, 63);//(in, 0, 1023, 0, 1023)
    ;//Do nothing

  if ( out < 0.5 )  pinMode(PWMPin, INPUT);   // This was added due to duty cycle only reaching as low as 1% min.
  else pinMode(PWMPin, OUTPUT);
  OCR0B = out;

Looking at the trialing edge of the PWM signal, it fluctuates by 200uS max. The leading edge is rock steady. If this is the cause of the issue, could an external crystal attached to the ATiny85 help remedy it?

That's normal with inductive loads, in detail when external force is applied to the damper.

If you want stricter current control then you have to handle feedback from the shunt and adjust the PWM duty cycle accordingly.

Why the 1N4001 (diagram in post#1).
It does absolutely nothing there.
It's in the wrong place if your load is inductive (should go across the load),
and the mosfet already has a built-in diode there.

Just as well, since a 1N4001 is not fast-recovery and not suitable for use with PWM. :upside_down_face:

What is the spec of the damper?
Can you post link to data/specs please?

Is 2kHz from the data sheet of the damper?

Can you connect the scope to the shunt output and show the current waveform?

Tom.. :grinning: :+1: :coffee: :australia:

The current fluctuations may be due to power supply.
I would measure (and show here)

  1. Drain-source voltage
  2. Voltage over the load
  3. The supply voltage (GND close to the shunt, probe at the load + end).

Is 150 mA significant if the current is 3 A?

You need a proper freewheel diode!

That's exactly how its supposed to work, the current waveform should be roughly an asymmetrical triangle wave. To reduce the amplitude of the current variation you can use a higher PWM frequency.

You need to be aware that the current shunt should be sampled in synchrony with the PWM for stablest behaviour. Or you can low-pass filter the current shunt signal (this will affect any control loop though, which might have to become slower to respond.)

Yes, I added it last thing. Should have added it across the load like you correctly said! Thanks

Thanks, is there a recommeded diode that I could try across the load?

At least 12V and 3A perhaps? Its not very critical, standard rectifiers are often used.

... and are too slow for PWM. For relays or mains frequency any diode is okay.

Would you know of any fast reacting diodes for PWM?

Search for "fast recovery diodes".

Use Schottky diode.