D.I.Y. Illuminated Tailcap - gChart Editions

I like. It’s fun to think I have a sort of legacy here.

the question would be if its running on a bleeder or needs some intelligent driver that connects battery+ with a FET when off
bleeder and MCU running might get even with 470Ohm too much drop to get a real voltage reading, or even power up as voltage drops

I had same problem with my comparator tail cap and too high current draws in the >1mA range, rund fine on PSU but with bleeder you got no real voltage reading as too high drop on bleeder

Great to see you on, PD!

Oh, and BOM added to the post

Thats a great question. My plan is to have it running on a bleeder, but I have not tested that yet (so keep that in mind before ordering parts, if someone is so inclined). I might have to make tweaks based on how it acts behind a bleeder.

Nice job gchart!
Especially like the decreasing lighted led’s to battery level indicator. :+1:

SUPER COOL!

Seems like with probably just a few very minor code changes you could use half green and half red LEDs and have a tail ring that fades from green to yellow to red.

The problem with fading is that requires ramping PWM up and down, which requires the MCU to be awake. Awake, the 416 will probably use 1mA (@3.3MHz). Asleep, it should be around 1uA. (datasheet pages 439 and 445, not my measured values). If battery drain isn’t too big of a concern, that definitely is a possibility!

Ok… I tested it in-flashlight. It’s a Convoy M1 with a Nanjg105c & 750 Ohm bleeder. Results seem mostly positive.

Firstly, it works. But a few observations:

  • I’ll definitely need to adjust the voltage detection levels. A 4.09V battery gave 6/8 LEDs. A 3.54V battery gave 3/8 LEDs.
  • The LEDs are dim during the animation, I’m guessing because the MCU is taking up most of the current. Not a big deal. I might even remove the animation. Not sure yet.
  • The first voltage check reads low. This is despite the fact that I take 16 ADC readings and trash them, then grab 8 readings and average them. I guess it’s just because it’s taking the reading on the coat tails of the animation? Dunno, I can probably code around it.
  • I can probably reduce the MCU current draw in active mode (ie, animation) by reducing the CPU frequency and making sure I have some other things disabled (like BOD). Freq is currently 3.3MHz, I think. I just rolled with the default, which I think is 20MHz with a divider of 6. Any idea whats a safe, low frequency to use?

gchart,

This is sort of off topic but what do you have your buck driver attached to for power? I’m looking for a similar setup.

This. It’s very basic, but it works for what I need right now.

An update…

I managed to decrease the MCU power draw considerably by changing the main clock to be driven from the 32.767 KHz internal ULP (ultra low power) RC oscillator instead of the prescaled 20MHz one.

I also managed to get a good grasp on the ADC readings by using the 8 LEDs to display the significant digits of the ADC readings in binary (each LED representing one bit of the ADC reading). It worked really slick. I took 7 measurements across the typical voltage range and got a great trend line with an R^2 value of 0.99.

So now that I have a calibrated formula, I just need to plug that into the source code, re-uploaded, and we should be in business!

Thanks! What are you using as a power source?

Mr gchart I like your project very much! I am looking forward to more update and improvements!!

Give that man a Bells! :beer:
Watching close with interest

Updates:

  • I made a few code tweaks yesterday and re-flashed it. I think it’s all done now! I put in several batteries at various voltages and the LEDs are lighting up exactly as they should. :smiley:
  • Switching to using the 32.768KHz oscillator for the clock really helped with power consumption during active state (and a bit in standby as well). The LEDs are no longer dim during the animation, as there is plenty of current available now
  • I used LED series resistors with less resistance than what I desired (used 30K, probably should have used 90K or so). With all the LEDs lit during standby, current consumption is 0.35mA (I typically aim for 0.12-0.18mA depending on the LED colors used). I think almost all of that is going to the LEDs. Only an immeasurable amount to the MCU (well, immeasurable with my DMM that only reads to 0.00mA).
  • During the active state with animation (one LED lit), the consumption is 0.05mA. That’s actually about how much current I figure the LED itself is consuming… battery voltage at 4.1V with measured LED vF of 2.5V using a 30K Ohm resistor: (4.1V - 2.5V)/30000Ω = 0.05mA. So even during active state (not sleep), the MCU is using almost no current.

Well, now that I know that power consumption during active state can be highly reduced using the ULP oscillator (~12uA), this actually could happen! :+1:

Hey, I think maybe you might have missed post #97 ? Is this what you’re looking for? If it’s not, just let me know.

I love where you’re going with your illuminated tailcap development gchart. I’ve just built one of your LVP tailcaps as my first non-emitter reflow and I’d love to build your voltage indicator design one day.

Even without a code change I think it would look good with four green, two yellow, and two red LEDs.

This is so sexy!

Nice implementation with the MCU! Now how do you take your ADC voltage readings exactly, with the first one being wrong? I might have a simple solution, if the first value affects the average too much.

It seems to be working fine at the moment, but I’d be curious to hear your ideas! Here’s an overview of the code:

Main()

  • Initialize the clock and pins
  • Run the animation
  • Shut the LEDs off and pause for 20ms to allow things to settle down
  • Run Set_Battery_Status
  • Initialize the RTC to wake us up every 60 minutes
  • Go to sleep (standby)

The RTC interrupt just clears the overflow flag and then calls Set_Battery_Status

Set_Battery_Status()

  • Turn off all the LEDs
  • Wait 10ms for things to settle down
  • Run Get_Voltage
  • Use the returned voltage to turn on desired LEDs

Get_Voltage()

  • Set Vbandgap ref to internal 2.5V
  • Set ADC ref to VDD
  • Enable the ADC, set it to 10-bit resolution
  • Get 15 ADC readings and throw them away
  • Get 8 ADC readings and add them together
  • Get the average of the 8 readings (bitshift: sum >> 3)
  • Use a calibrated formula to get the voltage. Standard formula is (1023*2.5)/reading. My formula is (2643.3/reading)+0.0267.
  • Turn off the ADC
  • Return the reading

It’s probably a bit wasteful, but I have 4K of program space to work with and I’m just turning on and off a few indicator LEDs so I wasn’t very concerned about peak efficiency.