I recently picked up and arduino nano kit and messed around with all the simple projects. I dont have much EE experience besides those so I have a question that might be pretty basic.

I am trying to make a simple travel lantern with a rechargeable Li-ion battery pack. It is working, but the voltage at the LED is below what I calculated it should be and thus the LED is dimmer than expected.

I'm using a 18650 3.7v Li-ion battery for power that is connected to a TP4056 charge/protect board. The TP4056 output is connected to a MT3608 step-up boost converter to boost the 3.7v up to 7v which powers the Nano through pin 30. I know that is not an efficient way to power it but I will be changing that in the future.

I want to use PWM to control the brightness using a rotary encoder and the push button to turn it on/off. The LED was salvaged from a flashlight I had around and after some research it looks like it is a cree xp-c which lists a forward voltage of 3.6v @ 350mA. To reduce the 5v max output of the arduino pins I made a voltage divider with R1 being a 100 ohm resistor and R2 being 330 ohms. This should cause the output between the resistors to be ~3.8v, but since the arduino puts out a bit less than 5v I expected ~3.6v output.

The issue is that I am getting 2.6v to the LED instead of the 3.6v it should be. I measured 4.5v from pin D6 to GND but only 2.6v after the divider. What could cause the voltage to be 1v lower than expected?

Lantern circuit design

Here is the code I have on the nano:

int tempPin = 0;

volatile boolean TurnDetected;  // need volatile for Interrupts
volatile boolean rotationdirection;  // CW or CCW rotation
volatile boolean isOn;
volatile boolean buttonPress;

const int PinCLK=2;   // White
const int PinDT=4;    // Orange
const int PinSW=3;    // Brown
const int PinLED=5;

int counter = 100;

// Interrupt routine runs if CLK goes from HIGH to LOW
void isr ()  {
  delay(4);  // delay for Debouncing
  if (digitalRead(PinCLK))
    rotationdirection= digitalRead(PinDT);
    rotationdirection= !digitalRead(PinDT);
  TurnDetected = true;
void isr1 ()  {
  delay(4);  // delay for Debouncing
    isOn = !isOn;
  buttonPress = true;

void setup() {
  digitalWrite(PinSW, HIGH); // Pull-Up resistor for switch

  attachInterrupt (0,isr,FALLING);
  attachInterrupt (digitalPinToInterrupt(PinSW),isr1,FALLING);


void loop() {

      int val = map(counter, 0, 100, 0, 255);
      analogWrite(PinLED, val);
    } else {
      digitalWrite(PinLED, LOW);

  if (TurnDetected)  {
    if (rotationdirection) {
    else {
    if(counter > 100){
    }else if (counter < 30){
      counter = 30;
    int val = map(counter, 0, 100, 0, 255);
    analogWrite(PinLED, val); 
    TurnDetected = false;  // do NOT repeat IF loop until new rotation 

1 Answer 1


Arduino outputs are typically limited to 20mA with a voltage drop of 0.3 to 0.8V depending on the microcontroller used.

For 350mA leds, you need at minimum a mosfet or transistor, and preferably a constant current driver.

Resistor voltage dividers will be very very poor in this type of situation. You'd be better off using just a single resistor.

  • \$\begingroup\$ It's my understanding that if I used a mosfet I would lose ability to use PWM to control the brightness of the LED. \$\endgroup\$
    – Loxez
    Sep 2, 2018 at 22:54
  • \$\begingroup\$ No, the mosfet would respond to the pwm just as much as the led. \$\endgroup\$
    – Passerby
    Sep 2, 2018 at 22:58
  • 1
    \$\begingroup\$ @Loxez Essentially, you don't need a voltage divider. R2 is causing the problem. Remove it entirely, and select a value for R1 that gives the correct current through the LED. \$\endgroup\$
    – Simon B
    Sep 3, 2018 at 8:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.