Controlling a LED strip's brightness using MOSFET and an optocoupling using PWM

Hi. New to Arduino and not very familiar with electronics.

Trying to control a LED strip's brightness using Arduino's PWM. First i built this scheme (from this topic http://forum.arduino.cc/index.php?topic=15993.15), but it didn't work for me:

|500x355

I assume it's totally incorrect. For some reason the author connected the FET's gate to the base, not the collector of the phototransistor. Also the load (a motor) is wrongly connected to the FET's source, not the drain. Or perhaps i didn't understand it correctly, and his schematic should work?

Here's my schematics (i made it based on what i have read about how MOSFETs and opto couplings work):

|500x338

The problem is that even if i analogWrite(9,1), the LEDs are already shining brightly, and I can not get a nice dimming effect, when the light is dim (by gradually incrementing PWM from 0 to 255) analogWrite(9,0) turns LEDs off, which is correct analogWrite(9,255) makes them shine 100%, which is also correct

I just would like for the brightness to increase linearly as i gradually increment PWM from 0 to 255. How can this be achieved? Currently it "jumps" to the bright shining when i change analogWrite(9,0) to analogWrite(9,1), and when i increment the PWM value further, I am getting a slight increment of the brightness.

Are there any possible problems in my schematics?

I would also like to control a DC motor using the same schematic (optocoupling+MOSFET). Would there be any problems in a long run?

Thank you.

Connect the transistor in the common emitter configuration. Collector resistor 10K. Take the collector to the gate. This will invert the logic. Assumption is there is current limiting in the led strip. You can change the 680 to a 220.

To get help, you must show us your complete sketch. Attach your code using the </> icon on the left side of the posting menu.

This is the code I am using:

LarryD:
To get help, you must show us your complete sketch. Attach your code using the </> icon on the left side of the posting menu.

byte brightness = 0;
int LEDSTRIP = 9;

void setup() {
  // put your setup code here, to run once:
  pinMode(LEDSTRIP, OUTPUT);
  Serial.begin(9600);
}

void processCommand(byte command) {
  switch(command) {
    case 'z': 
      analogWrite(LEDSTRIP, --brightness); //decrement brightness and set it for the pin LEDSTRIP
    break;

    case 'x':
      analogWrite(LEDSTRIP, ++brightness); //increment brightness and set it for the pin LEDSTRIP
    break;

    default:
      //the command is not supported
      break;
  }
}

void loop() {
  if(Serial.available()) {
    byte command = Serial.read();
    processCommand(command);
  }
}

So, when I send ‘x’ once, the LED strip is already shining half-way, not barely, as I am hoping it to.
If it send ‘x’ more times, it’ll shine brighter each time.
What I would like it to do - is to light up gradually and linearly from 0% to 100% as I increment PWM from 0 to 255.
Is it possible?

Connect the transistor in the common emitter configuration.

Do you mean I need to use base of the optocoupler’s phototransistor (connecting the base via a resistor to the emitter)?

You are not changing the brightness in that code, you need to use analogWrite to change the PWM. Serial.write sends data back to serial monitor that is all.

You should post all your code, you did not.

Do not connect the opto coupler's base to anything.

You are not changing the brightness in that code, you need to use analogWrite to change the PWM. Serial.write sends data back to serial monitor that is all.

You should post all your code, you did not.

Mike,

Whenever the computer sends 'x' via serial, the code is calling "analogWrite(LEDSTRIP, ++brightness)", which first increments brightness (initially it is 0 when the program starts) by 1, and then calls "analogWrite(9, 1)", "analogWrite(9, 2)", "analogWrite(9, 3)", ... (depending on how many times the computer sends x).

Whenever the computer sends 'z' the code is calling "analogWrite(LEDSTRIP, --brightness)"

So basically I can control Pin 9 PWM from the Arduino IDE's Serial Monitor (this part works) - the light slightly changes its brightness, although not the way i want it to (not linearly from 0% to 100%). Serial.write was there just for debugging. I removed it and updated my previous post to what my code looks like now.

Do not connect the opto coupler's base to anything.

Could you please confirm that this schematics is completely incorrect? |500x355

Strangely, the following schematics makes LED strip dim better. But it is mentioned everywhere that this is a bad way to connect MOSFET directly to arduino (because the MOSFET requires larger voltages to be applied to its GATE than what Arduino can provide on its PWM pin (5V)) and because there's a direct connection to arduino which potentially may damage the board.

Is it safe to use the following schematics? Since it seem to be working...

|500x271

Also is it safe to connect a small DC motor instead of the LED strip?

Thank you

I removed it and updated my previous post to what my code looks like now.

Please read this:- How to use this forum

Your edits made my post look pretty stupid. The forum guidelines say you should not edit posts to do that but you did!

Serial.write was there just for debugging.

That won't work you need to use Serial.print

Could you please confirm that this schematics is completely incorrect?

Yes it is total crap.

Is it safe to use the following schematics?

You need to add a resistor 120R minimum between gate and the arduino to limit the peak current from the pin to a safe level.

Also is it safe to connect a small DC motor instead of the LED strip?

Only once you have wired a reverse bias diode across the motor.

Your edits made my post look pretty stupid. The forum guidelines say you should not edit posts to do that but you did!

Sorry

You need to add a resistor 120R minimum between gate and the arduino to limit the peak current from the pin to a safe level.

Thanks, added a 220 Ohm resistor.

I need to have two things controlled from an arduino - a led strip and a motor (both are 12V loads).

Here’s the schematics I ended up with (without a reversed diode on the motor, I am going to add it). Is there any potential problem with this schematics? Wish I was good with electronics to understand what’s may go wrong. Could anyone please correct me, if it’s poorly designed? It seems to be working for me right now (the motor is spinning and the lights are dimming)

Here’s the code:

int LEDSTRIP = 9;
int MOTOR = 10;
int BOARDLED = 13;
int brightness = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(LEDSTRIP, OUTPUT);
  pinMode(MOTOR, OUTPUT);
  pinMode(BOARDLED, OUTPUT);
  Serial.begin(9600);
}

void processCommand(byte command) {
  switch(command) {
    case '2': //dim lights on
      Serial.print("Turning the light on\n");
        
      for(int i=0; i<=255; i++) {
        analogWrite(LEDSTRIP,i);
        //analogWrite(LEDSTRIP, 0.003921568*i*i);
        delay(20);
      }
      break;
      
    case '1': //dim lights off
          Serial.print("Turning the light off\n");
      for(int i=255; i>=0; i--) {
        analogWrite(LEDSTRIP,i);
        //analogWrite(LEDSTRIP, 0.003921568*i*i);
        delay(20);
      }
      break;

    case '4': //turn motor on
          Serial.print("Turning the motor on\n");
      analogWrite(MOTOR,255);
      break;

    case '3': //turn motor off
          Serial.print("Turning the motor off\n");
      analogWrite(MOTOR,0);
      break;

    case 'z': 
      analogWrite(LEDSTRIP, --brightness);
      //Serial.write(brightness);
    break;

    case 'x':
      analogWrite(LEDSTRIP, ++brightness);
      //Serial.write(brightness);
    break;
    default:
      //the command is not supported
      break;
  }
}

void loop() {
  if(Serial.available()) {
    byte command = Serial.read();
    processCommand(command);
  }
}

Thank you

You need a diode across the motor. That is cathode to the +12 and anode to the FET's drain.

Thanks Mike. Yes, I paralleled the motor with a diode (just forgot to put it on the schematics).

The IRF540 is NOT a good match for a 5volt Arduino. It needs 10volt or more at the gate to fully turn on.

Better use a LOGIC fet. Leo..

Why do you say that It is bad?

Because it takes 10V to fully turn it on. With only 5V from the Arduino it will have quite a high turn on resistance and so will reduce the current in the load and get hotter than it normally would. It will be a problem when you run any significant current through it like a motor.

The IRF540 is NOT a good match for a 5volt Arduino. It needs 10volt or more at the gate to fully turn on.

Leo, could you suggest some common mosfet, that you would normally use with Arduino for motor-like currents, instead of the irf540n? I assume the resistor 220 ohm resistor should be kept if i replace the mosfet?

IRL540 is one example: http://www.vishay.com/docs/91300/91300.pdf