How to improve my battery measurement circuit? - eviltoast

I am powering a 5V microcontroller (arduino clone, atmega328p) using a 9V block and a buck converter. Now I want to let the microcontroller occasionally measure the battery voltage, so I can get an idea of how full it is.

My first idea was to use a simple voltage divider:

I’ve chosen the resistor values so that:

  • the voltage at the measure output is < 1.1V, to be able to use the 1.1V internal reference of the atmega’s ADC
  • R1 || R2 < 10kΩ, since the atmega datasheet says “The ADC is optimized for analog signals with an output impedance of approximately 10 kΩ or less”

This is great and all, but what bothers me is that this circuit will constantly draw ~100µA from the battery.

So, my next thought was to add a mosfet to the divider, to switch it on only while measuring:

This is obviously bad, because now when the mosfet is off, the ADC input sees the whole battery voltage.

To address that issue, I’ve added a second mosfet into the measure path:

This works, and it does not draw any current, except while measuring.

However, it’s quite a few parts. So I’m curious if anyone has an idea how to do this with just a single mosfet. It seems to me like it should be possible, but I haven’t figured out how.

Oh, and if I’m doing something stupid here, please tell me :)

  • WaterWaiver@aussie.zone
    link
    fedilink
    English
    arrow-up
    7
    arrow-down
    1
    ·
    edit-2
    1 year ago

    You could probably increase the 82K and 10K resistors to be much bigger (by a factor of 10x or maybe even 100x). Lookup the input impedance for the ADC of your model of ATmega, as long as it’s >10x the size of your resistors then your circuit will probably be accurate enough.

    A couple more things to keep in mind:

    • a fresh alkaline 9V battery is actually 9.6V or more, not 9V.
    • 9V battery voltages droop noticeably when under load because of their high internal resistance. Make sure to measure under the same conditions.
    • nilclass@discuss.tchncs.deOP
      link
      fedilink
      English
      arrow-up
      4
      arrow-down
      1
      ·
      1 year ago

      You could probably increase the 82K and 10K resistors to be much bigger

      That’s what I thought initially, but this stackoverflow post dissuaded me. The argument there is that the measurement will be wrong, if the input current is not enough to charge the internal cap within the measurement period. But I’ve done some testing now, and measurements done with 820k and 100k agree well with what my voltmeter measures, so I’ll go with this solution!

      a fresh alkaline 9V battery is actually 9.6V or more, not 9V.

      Indeed! 9.6V * 10k/92k = 1.04V is still below 1.1V, so I should be fine in this case :)

      9V battery voltages droop noticeably when under load because of their high internal resistance. Make sure to measure under the same conditions.

      This is a good point!

      My firmware will be pretty monotonic though, basically:

      1. wake up
      2. measure battery
      3. measure some other sensors (the actual task of the device)
      4. turn on a transceiver, send all the measurements (including battery voltage)
      5. turn off transceiver & go to sleep

      So, the load should be always the same at step (2).

      • Brendan@mastodon.brendans-bits.com
        link
        fedilink
        arrow-up
        3
        ·
        1 year ago

        @nilclass

        @WaterWaiver

        From the stack exchange post: " 10 kΩ or less source resistance is recommended, otherwise the low pass filter effect of the capacitor with the source resistance becomes a major issue, requiring a longer sampling time for conversion and as a result limiting the maximum frequency."

        In other words: a higher source impedance (caused by large resistors) is only going to drastically affect the results when you need to take fast repeated measurements (e.g. an AC source)

  • Yonrak@feddit.uk
    link
    fedilink
    English
    arrow-up
    4
    ·
    edit-2
    1 year ago

    Could you do similar to diagram 2, but instead of an N-FET use a P-FET between the battery and first resistor in the potential divider?

    Add a gate pull up resistor to source to ensure the FET is off by default, have the micro pull the gate down to take a measurement. You’ll probably need to add another resistor on the control pin to 0V to limit the voltage there also, but those two can be much much higher values to really limit current. Or use a zener/TVS diode instead of second resistor to clamp the voltage instead of dividing (more robust).

    Switch it with an NFET

    The micro will see 0V or divided/clamped battery voltage on the measurement pin.

    • nilclass@discuss.tchncs.deOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      1 year ago

      Could you do similar to diagram 2, but instead of an N-FET use a P-FET between the battery and first resistor in the potential divider?

      That’s a great idea! Unfortunately I don’t have a P-FET lying around, so cannot try it right now.

      Or use a zener/TVS diode instead of second resistor to clamp the voltage instead of dividing (more robust).

      Not sure I understand this point. Which resistor would you replace with a diode?

      • Yonrak@feddit.uk
        link
        fedilink
        English
        arrow-up
        3
        ·
        edit-2
        1 year ago

        Not sure I understand this point. Which resistor would you replace with a diode?

        Sorry, I think I was talking nonesense (doing this in my head and just woke up 😅).

        Not sure it’ll work with just a P-FET actually. You’ll likely need to control the PFET with a NFET, otherwise you still end up with too high a voltage on your control pin when the FET is off due to the gate pullup (unless you can use a fet with a very high Vgs Threshold and then drive it push/pull from the micro, but this isn’t really best practice).

        The above comment about diodes was to protect the microcontroller pin, but you end up not being able to control the FET doing it that way.

        I think either your existing Option 3 or PFET upstream of the divider, switched via an N-FET is the way to go.

  • jjagaimo@lemmy.ca
    link
    fedilink
    English
    arrow-up
    3
    ·
    edit-2
    1 year ago

    You could use a single MOSFET on the high side of the divider and use a cap + diode to boost the voltage and fully turn on the FET:

    My gate driver is fairly crude but you could probably make something a bit better with a PNP transistor and either pull it down or leave it floating, or instead use a szaiklai pair

    • nilclass@discuss.tchncs.deOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      edit-2
      1 year ago

      Hm, I don’t understand how this is supposed to work - is that a n-channel or p-channel FET?

      When I sketch it using falstad’s circuitjs, it looks like the FET (n-channel) is a little bit on all the time

      and fully on, when a pulse is applied

      Source:

      spoiler
      $ 1 0.000005 10.20027730826997 50 5 43 5e-11
      r 144 80 144 176 0 1000
      r 0 192 96 192 0 100
      t 96 192 144 192 0 1 -8.999999980890745 9.099999980846458e-10 100 default
      c 144 176 304 176 0 0.000001 -1.7996761414451612e-8 0
      f 304 176 384 176 32 2 0.02
      d 304 80 304 176 2 default
      r 384 192 384 272 0 1000
      r 384 272 384 352 0 1000
      g 384 352 384 384 0 0
      g 144 208 144 256 0 0
      w 144 80 304 80 0
      w 384 160 384 80 0
      w 384 80 304 80 0
      v 528 256 528 208 0 0 40 9 0 0 0.5
      w 528 256 528 352 0
      w 528 352 384 352 0
      w 528 208 528 80 0
      w 528 80 384 80 0
      g -48 208 -48 256 0 0
      R -48 176 -48 128 0 0 40 5 0 0 0.5
      S 0 192 -48 192 0 0 false 0 2
      p 384 272 272 272 3 0 0
      g 272 272 272 304 0 0
      

      • jjagaimo@lemmy.ca
        link
        fedilink
        English
        arrow-up
        3
        ·
        1 year ago

        It is an N channel FET. The concept is called “bootstrapping” since Vgs needs to be greater than Vth for the MOSFET to be on. When the FET is on the high side and you want the full 9V on the output, you use the diode to charge the capacitor, and the other side of the cap is 0V. Then, when the other side of the cap is connected to 9V, the charge on the cap can’t go anywhere so the voltage on the other side jumps to 18V. This creates a Vgs of 9V. Ideally you would have something better to drive the gate to fully turn off the FET, but I just used a quick and dirty driver where the bootstrap capacitor directly feeds the gate instead of being the input to the driver. Because if this, the Vgs doesn’t drop completely to 0

        • nilclass@discuss.tchncs.deOP
          link
          fedilink
          English
          arrow-up
          1
          ·
          1 year ago

          Nice, than you for sharing!

          I won’t be using this for my measurement issue (the other options are much simpler, and i was aiming for less parts, not more), but I’ll do some experiments to familiarize myself with bootstrapping

  • Stoney@aussie.zone
    link
    fedilink
    English
    arrow-up
    2
    ·
    1 year ago

    increase the resistors by a factor of 100 or so and add a very small cap across the lower one. The cap inside the ADC is absolutely tiny, pF at best. So a 100nF cap would easily do the trick and supply the voltage as required.